summaryrefslogtreecommitdiffstats
path: root/2021
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--2021/captions/faster.md512
1 files changed, 512 insertions, 0 deletions
diff --git a/2021/captions/faster.md b/2021/captions/faster.md
new file mode 100644
index 00000000..be9b5083
--- /dev/null
+++ b/2021/captions/faster.md
@@ -0,0 +1,512 @@
+<a name="transcript"></a>
+# Transcript
+
+[[!template new="1" text="Hi. Greetings from the cloudy St. Petersburg." start="00:00:01.120" video="mainVideo" id=subtitle]]
+[[!template text="My name is Dmitry Gutov." start="00:00:04.640" video="mainVideo" id=subtitle]]
+[[!template text="I write Ruby by day, Emacs Lisp by night" start="00:00:06.080" video="mainVideo" id=subtitle]]
+[[!template text="when I don't do anything else." start="00:00:09.280" video="mainVideo" id=subtitle]]
+[[!template text="You might know my work" start="00:00:12.080" video="mainVideo" id=subtitle]]
+[[!template text="from a number of third-party packages" start="00:00:14.559" video="mainVideo" id=subtitle]]
+[[!template text="as well as built-in ones." start="00:00:18.160" video="mainVideo" id=subtitle]]
+[[!template text="The idea for this talk came out from" start="00:00:22.240" video="mainVideo" id=subtitle]]
+[[!template text="an improvement request" start="00:00:25.599" video="mainVideo" id=subtitle]]
+[[!template text="for the performance of grep-like commands" start="00:00:26.800" video="mainVideo" id=subtitle]]
+[[!template text="using the xref interface" start="00:00:32.960" video="mainVideo" id=subtitle]]
+[[!template text="and its storage types, container types" start="00:00:35.200" video="mainVideo" id=subtitle]]
+[[!template text="for the search results," start="00:00:43.280" video="mainVideo" id=subtitle]]
+[[!template text="complaining that it's not as fast" start="00:00:47.840" video="mainVideo" id=subtitle]]
+[[!template text="as it potentially could have been" start="00:00:51.440" video="mainVideo" id=subtitle]]
+[[!template text="when there are lots of search results" start="00:00:54.320" video="mainVideo" id=subtitle]]
+[[!template text="coming for a given search." start="00:00:58.239" video="mainVideo" id=subtitle]]
+[[!template text="I have noticed myself that" start="00:01:01.600" video="mainVideo" id=subtitle]]
+[[!template text="when working on it, and probably before." start="00:01:06.159" video="mainVideo" id=subtitle]]
+[[!template text="My approach to optimizing Lisp code" start="00:01:10.159" video="mainVideo" id=subtitle]]
+[[!template text="has changed recently-ish," start="00:01:16.560" video="mainVideo" id=subtitle]]
+[[!template text="and I'd like to talk about it here." start="00:01:21.680" video="mainVideo" id=subtitle]]
+[[!template text="This talk is for people who already" start="00:01:26.960" video="mainVideo" id=subtitle]]
+[[!template text="know how to write some Emacs Lisp" start="00:01:34.079" video="mainVideo" id=subtitle]]
+[[!template text="to solve their problems" start="00:01:37.040" video="mainVideo" id=subtitle]]
+[[!template text="and who have possibly encountered" start="00:01:38.880" video="mainVideo" id=subtitle]]
+[[!template text="some performance issues doing that." start="00:01:43.360" video="mainVideo" id=subtitle]]
+[[!template text="Also, if you want to contribute" start="00:01:49.200" video="mainVideo" id=subtitle]]
+[[!template text="some improvements to the code" start="00:01:51.600" video="mainVideo" id=subtitle]]
+[[!template text="that is already in Emacs" start="00:01:54.799" video="mainVideo" id=subtitle]]
+[[!template text="or to other packages" start="00:01:56.960" video="mainVideo" id=subtitle]]
+[[!template text="which are owned by somebody else," start="00:02:02.159" video="mainVideo" id=subtitle]]
+[[!template text="it should also be helpful. Let's start." start="00:02:04.479" video="mainVideo" id=subtitle]]
+[[!template text="First of all, about Emacs and Emacs Lisp." start="00:02:13.520" video="mainVideo" id=subtitle]]
+[[!template text="It's not the fastest language." start="00:02:18.640" video="mainVideo" id=subtitle]]
+[[!template text="Let's switch to the notes." start="00:02:21.360" video="mainVideo" id=subtitle]]
+[[!template text="I hope the font is big enough" start="00:02:26.560" video="mainVideo" id=subtitle]]
+[[!template text="to be readable on this video, really hope." start="00:02:31.440" video="mainVideo" id=subtitle]]
+[[!template new="1" text="Emacs Lisp is not the fastest of the bunch." start="00:02:36.480" video="mainVideo" id=subtitle]]
+[[!template text="The garbage collector creates pauses" start="00:02:40.160" video="mainVideo" id=subtitle]]
+[[!template text="whenever it needs to sweep data." start="00:02:44.400" video="mainVideo" id=subtitle]]
+[[!template text="The interpreter is not the fastest one," start="00:02:48.800" video="mainVideo" id=subtitle]]
+[[!template text="even though the native compilation branch" start="00:02:51.760" video="mainVideo" id=subtitle]]
+[[!template text="is improving on that by twice" start="00:02:54.720" video="mainVideo" id=subtitle]]
+[[!template text="in certain scenarios, which is good." start="00:02:59.120" video="mainVideo" id=subtitle]]
+[[!template text="The standard library or functions" start="00:03:04.640" video="mainVideo" id=subtitle]]
+[[!template text="for working with collections, for example," start="00:03:10.560" video="mainVideo" id=subtitle]]
+[[!template text="are not so uniformly great." start="00:03:12.800" video="mainVideo" id=subtitle]]
+[[!template text="So there is some work to be done there." start="00:03:17.599" video="mainVideo" id=subtitle]]
+[[!template text="Maybe you can contribute" start="00:03:20.080" video="mainVideo" id=subtitle]]
+[[!template text="the next improvement in there." start="00:03:22.239" video="mainVideo" id=subtitle]]
+[[!template text="And also, if your package displays stuff," start="00:03:26.640" video="mainVideo" id=subtitle]]
+[[!template text="it has a visual component," start="00:03:33.200" video="mainVideo" id=subtitle]]
+[[!template text="then you might have to deal with" start="00:03:35.040" video="mainVideo" id=subtitle]]
+[[!template text="some drawbacks of the display engine" start="00:03:36.959" video="mainVideo" id=subtitle]]
+[[!template text="which might slow to a crawl" start="00:03:43.120" video="mainVideo" id=subtitle]]
+[[!template text="when your code has..." start="00:03:47.760" video="mainVideo" id=subtitle]]
+[[!template text="when you're trying to display lines" start="00:03:53.680" video="mainVideo" id=subtitle]]
+[[!template text="which are a little too long--" start="00:03:56.560" video="mainVideo" id=subtitle]]
+[[!template text="trying to print a long line, for example--" start="00:04:00.319" video="mainVideo" id=subtitle]]
+[[!template text="or you are using a lot of overlays," start="00:04:03.120" video="mainVideo" id=subtitle]]
+[[!template text="if you know what it is." start="00:04:07.120" video="mainVideo" id=subtitle]]
+[[!template text="With lots of overlays" start="00:04:09.120" video="mainVideo" id=subtitle]]
+[[!template text="on the same visual line, in particular." start="00:04:12.640" video="mainVideo" id=subtitle]]
+[[!template new="1" text="But okay. The first thing to understand," start="00:04:19.840" video="mainVideo" id=subtitle]]
+[[!template text="and I hope everybody who's done" start="00:04:24.160" video="mainVideo" id=subtitle]]
+[[!template text="some programming in the past knows," start="00:04:27.680" video="mainVideo" id=subtitle]]
+[[!template text="it's: first you write correctly," start="00:04:29.520" video="mainVideo" id=subtitle]]
+[[!template text="and then you try to benchmark." start="00:04:35.120" video="mainVideo" id=subtitle]]
+[[!template text="and see where the problems are," start="00:04:37.360" video="mainVideo" id=subtitle]]
+[[!template text="if there are any." start="00:04:39.199" video="mainVideo" id=subtitle]]
+[[!template text="So first do it right, then do it fast." start="00:04:40.720" video="mainVideo" id=subtitle]]
+[[!template text="How do we find the hotspots," start="00:04:45.919" video="mainVideo" id=subtitle]]
+[[!template text="the bottlenecks on the second step?" start="00:04:50.720" video="mainVideo" id=subtitle]]
+[[!template text="We try to do some profiling" start="00:04:52.400" video="mainVideo" id=subtitle]]
+[[!template text="or measuring how long the code takes." start="00:04:54.720" video="mainVideo" id=subtitle]]
+[[!template text="Emacs has two different profilers." start="00:04:58.960" video="mainVideo" id=subtitle]]
+[[!template new="1" text="One is the native profiler," start="00:05:03.039" video="mainVideo" id=subtitle]]
+[[!template text="which as I recall was contributed by" start="00:05:05.440" video="mainVideo" id=subtitle]]
+[[!template text="Tomohiro Matsuyama, the author" start="00:05:10.639" video="mainVideo" id=subtitle]]
+[[!template text="of the autocomplete package" start="00:05:13.280" video="mainVideo" id=subtitle]]
+[[!template text="back in Emacs 24.3, apparently." start="00:05:16.240" video="mainVideo" id=subtitle]]
+[[!template text="It's a low overhead profiler." start="00:05:22.720" video="mainVideo" id=subtitle]]
+[[!template text="It's sampling, which is good on one hand" start="00:05:24.320" video="mainVideo" id=subtitle]]
+[[!template text="but might be less good on the other hand." start="00:05:31.520" video="mainVideo" id=subtitle]]
+[[!template text="Let's try using it." start="00:05:33.919" video="mainVideo" id=subtitle]]
+[[!template text="So we start with profiler-start." start="00:05:35.199" video="mainVideo" id=subtitle]]
+[[!template text="Let's just ask for CPU profiling here," start="00:05:40.960" video="mainVideo" id=subtitle]]
+[[!template text="but it also can profile memory locations." start="00:05:44.960" video="mainVideo" id=subtitle]]
+[[!template text="Let's try a search for some string" start="00:05:48.320" video="mainVideo" id=subtitle]]
+[[!template text="in the current project." start="00:05:56.400" video="mainVideo" id=subtitle]]
+[[!template text="Let's do it a few times, maybe three times," start="00:06:01.360" video="mainVideo" id=subtitle]]
+[[!template text="so the profiler has more data to work with." start="00:06:04.080" video="mainVideo" id=subtitle]]
+[[!template text="Let's call the report." start="00:06:09.360" video="mainVideo" id=subtitle]]
+[[!template text="Okay. So here we have the tree," start="00:06:13.680" video="mainVideo" id=subtitle]]
+[[!template text="the execution tree with percentages" start="00:06:16.960" video="mainVideo" id=subtitle]]
+[[!template text="of the time spent in each function." start="00:06:19.360" video="mainVideo" id=subtitle]]
+[[!template text="You can unwrap it by going up and down" start="00:06:22.960" video="mainVideo" id=subtitle]]
+[[!template text="and pressing TAB to unwrap every element." start="00:06:25.840" video="mainVideo" id=subtitle]]
+[[!template text="This is weird." start="00:06:35.039" video="mainVideo" id=subtitle]]
+[[!template text="Okay, here we see that the actual command" start="00:06:52.000" video="mainVideo" id=subtitle]]
+[[!template text="that was called only takes" start="00:06:55.199" video="mainVideo" id=subtitle]]
+[[!template text="8% of the whole runtime," start="00:06:56.639" video="mainVideo" id=subtitle]]
+[[!template text="meaning the input was..." start="00:06:59.599" video="mainVideo" id=subtitle]]
+[[!template text="The command took not enough time" start="00:07:07.759" video="mainVideo" id=subtitle]]
+[[!template text="for us to really dig into it." start="00:07:10.960" video="mainVideo" id=subtitle]]
+[[!template text="Let's try a shorter input with more matches." start="00:07:13.360" video="mainVideo" id=subtitle]]
+[[!template text="So profiler-start again, CPU." start="00:07:18.960" video="mainVideo" id=subtitle]]
+[[!template text="Let's search for list." start="00:07:25.680" video="mainVideo" id=subtitle]]
+[[!template text="Don't mind the minibuffer just yet." start="00:07:34.240" video="mainVideo" id=subtitle]]
+[[!template text="Okay. So let's look at the report." start="00:07:40.160" video="mainVideo" id=subtitle]]
+[[!template text="We can unwrap it here, and we see" start="00:07:47.680" video="mainVideo" id=subtitle]]
+[[!template text="52% of the time was spent doing this," start="00:07:52.000" video="mainVideo" id=subtitle]]
+[[!template text="at least according to the profile." start="00:07:55.759" video="mainVideo" id=subtitle]]
+[[!template text="We can unwrap it, see the description" start="00:07:58.240" video="mainVideo" id=subtitle]]
+[[!template text="of any function that was called" start="00:08:00.960" video="mainVideo" id=subtitle]]
+[[!template text="by hitting d, or even jump to it" start="00:08:02.800" video="mainVideo" id=subtitle]]
+[[!template text="by tapping f." start="00:08:08.479" video="mainVideo" id=subtitle]]
+[[!template text="By going down the stream," start="00:08:12.960" video="mainVideo" id=subtitle]]
+[[!template text="we unwrap it with TAB," start="00:08:16.160" video="mainVideo" id=subtitle]]
+[[!template text="you can see where time was spent." start="00:08:18.240" video="mainVideo" id=subtitle]]
+[[!template text="One of the bigger drawbacks" start="00:08:22.400" video="mainVideo" id=subtitle]]
+[[!template text="of this profiler is the arithmetics" start="00:08:25.199" video="mainVideo" id=subtitle]]
+[[!template text="don't always work out," start="00:08:30.639" video="mainVideo" id=subtitle]]
+[[!template text="like you might have..." start="00:08:39.200" video="mainVideo" id=subtitle]]
+[[!template text="This is not a good example," start="00:08:45.760" video="mainVideo" id=subtitle]]
+[[!template text="but okay, you have 14% spent in here," start="00:08:47.519" video="mainVideo" id=subtitle]]
+[[!template text="but when we expand this entry," start="00:08:52.640" video="mainVideo" id=subtitle]]
+[[!template text="we only see like 6%, 3%, and 0%." start="00:08:57.200" video="mainVideo" id=subtitle]]
+[[!template text="Different sum, sometimes even bigger than that." start="00:09:01.760" video="mainVideo" id=subtitle]]
+[[!template text="So the native profiler" start="00:09:06.640" video="mainVideo" id=subtitle]]
+[[!template text="can give an accurate picture" start="00:09:10.800" video="mainVideo" id=subtitle]]
+[[!template text="and it has little overhead," start="00:09:13.200" video="mainVideo" id=subtitle]]
+[[!template text="but the specific numbers" start="00:09:15.920" video="mainVideo" id=subtitle]]
+[[!template text="are not very precise" start="00:09:20.399" video="mainVideo" id=subtitle]]
+[[!template text="because the principle is probabilistic." start="00:09:22.959" video="mainVideo" id=subtitle]]
+[[!template text="Let's stop here." start="00:09:28.640" video="mainVideo" id=subtitle]]
+[[!template new="1" text="There is another package called elp," start="00:09:31.200" video="mainVideo" id=subtitle]]
+[[!template text="Emacs Lisp Profiler," start="00:09:36.959" video="mainVideo" id=subtitle]]
+[[!template text="which is much older than that." start="00:09:39.360" video="mainVideo" id=subtitle]]
+[[!template text="It allows us to instrument" start="00:09:43.440" video="mainVideo" id=subtitle]]
+[[!template text="just specific functions or a package." start="00:09:47.920" video="mainVideo" id=subtitle]]
+[[!template text="We're instrumenting the xref package here." start="00:09:53.600" video="mainVideo" id=subtitle]]
+[[!template text="It works through advice. You can see" start="00:09:57.680" video="mainVideo" id=subtitle]]
+[[!template text="the description of one of the functions" start="00:10:01.360" video="mainVideo" id=subtitle]]
+[[!template text="in the package, and we see" start="00:10:03.279" video="mainVideo" id=subtitle]]
+[[!template text="that it has had :around device added." start="00:10:04.320" video="mainVideo" id=subtitle]]
+[[!template text="If we run the same search," start="00:10:12.640" video="mainVideo" id=subtitle]]
+[[!template text="we can see that -- when it finishes --" start="00:10:18.000" video="mainVideo" id=subtitle]]
+[[!template text="the table of all the numbers," start="00:10:21.360" video="mainVideo" id=subtitle]]
+[[!template text="that every function in the package" start="00:10:30.399" video="mainVideo" id=subtitle]]
+[[!template text="has been called, and the times" start="00:10:32.640" video="mainVideo" id=subtitle]]
+[[!template text="which the runtime has spent inside of them." start="00:10:41.680" video="mainVideo" id=subtitle]]
+[[!template text="sorted by impact, as it understands that." start="00:10:48.000" video="mainVideo" id=subtitle]]
+[[!template text="The main problem with this profiler is" start="00:10:55.040" video="mainVideo" id=subtitle]]
+[[!template text="it is slower because it adds overhead" start="00:11:00.079" video="mainVideo" id=subtitle]]
+[[!template text="to every function call," start="00:11:04.160" video="mainVideo" id=subtitle]]
+[[!template text="so it, in the end, might give an impression" start="00:11:06.880" video="mainVideo" id=subtitle]]
+[[!template text="that functions with lots of calls," start="00:11:11.519" video="mainVideo" id=subtitle]]
+[[!template text="which have been called a lot of times," start="00:11:19.519" video="mainVideo" id=subtitle]]
+[[!template text="are more important," start="00:11:21.839" video="mainVideo" id=subtitle]]
+[[!template text="hotter than they actually are," start="00:11:26.880" video="mainVideo" id=subtitle]]
+[[!template text="because it slows down" start="00:11:29.279" video="mainVideo" id=subtitle]]
+[[!template text="every such function call," start="00:11:30.959" video="mainVideo" id=subtitle]]
+[[!template text="including the subsequent calls" start="00:11:32.640" video="mainVideo" id=subtitle]]
+[[!template text="that these functions do" start="00:11:35.279" video="mainVideo" id=subtitle]]
+[[!template text="inside the same package." start="00:11:38.160" video="mainVideo" id=subtitle]]
+[[!template text="So it's a good way to analyze and drill down" start="00:11:40.560" video="mainVideo" id=subtitle]]
+[[!template text="to see which functions here" start="00:11:48.240" video="mainVideo" id=subtitle]]
+[[!template text="take a lot of time," start="00:11:50.320" video="mainVideo" id=subtitle]]
+[[!template text="but just keep in mind" start="00:11:51.200" video="mainVideo" id=subtitle]]
+[[!template text="that sometimes you might end up" start="00:11:53.839" video="mainVideo" id=subtitle]]
+[[!template text="trying to optimize one of these" start="00:11:57.760" video="mainVideo" id=subtitle]]
+[[!template text="smaller functions called" start="00:12:00.079" video="mainVideo" id=subtitle]]
+[[!template text="or usually smaller, and that the result" start="00:12:01.600" video="mainVideo" id=subtitle]]
+[[!template text="might not actually affect" start="00:12:09.279" video="mainVideo" id=subtitle]]
+[[!template text="the production runtime at all." start="00:12:11.040" video="mainVideo" id=subtitle]]
+[[!template text="But it's still a good tool," start="00:12:18.720" video="mainVideo" id=subtitle]]
+[[!template text="especially when you already know" start="00:12:22.240" video="mainVideo" id=subtitle]]
+[[!template text="which set of actions you are interested in," start="00:12:25.440" video="mainVideo" id=subtitle]]
+[[!template text="and which functions might be slower." start="00:12:30.560" video="mainVideo" id=subtitle]]
+[[!template text="elp allows you to instrument a package" start="00:12:33.760" video="mainVideo" id=subtitle]]
+[[!template text="or a set of functions. Just don't forget" start="00:12:37.120" video="mainVideo" id=subtitle]]
+[[!template text="to un-instrument them all afterwards," start="00:12:42.720" video="mainVideo" id=subtitle]]
+[[!template text="or else your session," start="00:12:49.600" video="mainVideo" id=subtitle]]
+[[!template text="your subsequent optimization efforts" start="00:12:52.000" video="mainVideo" id=subtitle]]
+[[!template text="might not work as well as you might" start="00:12:55.920" video="mainVideo" id=subtitle]]
+[[!template text="want to work." start="00:12:59.360" video="mainVideo" id=subtitle]]
+[[!template new="1" text="And there's also this very nice," start="00:13:01.360" video="mainVideo" id=subtitle]]
+[[!template text="very handy package called benchmark," start="00:13:04.560" video="mainVideo" id=subtitle]]
+[[!template text="which unfortunately" start="00:13:09.600" video="mainVideo" id=subtitle]]
+[[!template text="not everybody knows about." start="00:13:12.480" video="mainVideo" id=subtitle]]
+[[!template text="It turns out that a lot of" start="00:13:16.000" video="mainVideo" id=subtitle]]
+[[!template text="older Emacs Lisp developers," start="00:13:21.519" video="mainVideo" id=subtitle]]
+[[!template text="users, package developers usually have" start="00:13:30.079" video="mainVideo" id=subtitle]]
+[[!template text="some benchmarking macros of their own." start="00:13:34.160" video="mainVideo" id=subtitle]]
+[[!template text="But there is this package" start="00:13:38.000" video="mainVideo" id=subtitle]]
+[[!template text="with perfectly usable interface" start="00:13:42.880" video="mainVideo" id=subtitle]]
+[[!template text="which doesn't require you" start="00:13:46.160" video="mainVideo" id=subtitle]]
+[[!template text="to define something else," start="00:13:49.199" video="mainVideo" id=subtitle]]
+[[!template text="especially when you are in" start="00:13:51.120" video="mainVideo" id=subtitle]]
+[[!template text="an emacs -Q session" start="00:13:52.560" video="mainVideo" id=subtitle]]
+[[!template text="trying to benchmark your code" start="00:13:57.120" video="mainVideo" id=subtitle]]
+[[!template text="in a bare Emacs. So it has" start="00:14:00.480" video="mainVideo" id=subtitle]]
+[[!template text="two main endpoints, I would say." start="00:14:05.440" video="mainVideo" id=subtitle]]
+[[!template text="First one is the benchmark macro," start="00:14:09.680" video="mainVideo" id=subtitle]]
+[[!template text="and the second one is benchmark-progn." start="00:14:14.480" video="mainVideo" id=subtitle]]
+[[!template text="benchmark is a function," start="00:14:19.199" video="mainVideo" id=subtitle]]
+[[!template text="and benchmark-progn is a macro." start="00:14:20.399" video="mainVideo" id=subtitle]]
+[[!template text="The first one you can use by specifying" start="00:14:25.040" video="mainVideo" id=subtitle]]
+[[!template text="the number of iterations and the form." start="00:14:27.839" video="mainVideo" id=subtitle]]
+[[!template text="I hope the minibuffer is easy to read here." start="00:14:30.480" video="mainVideo" id=subtitle]]
+[[!template text="For instance, we can take this long list" start="00:14:36.800" video="mainVideo" id=subtitle]]
+[[!template text="and try nreverse-ing it," start="00:14:43.360" video="mainVideo" id=subtitle]]
+[[!template text="and we see how long that takes." start="00:14:44.800" video="mainVideo" id=subtitle]]
+[[!template text="Then you can do it," start="00:14:49.680" video="mainVideo" id=subtitle]]
+[[!template text="adjust the inner code," start="00:14:54.160" video="mainVideo" id=subtitle]]
+[[!template text="and then basically compare" start="00:14:55.600" video="mainVideo" id=subtitle]]
+[[!template text="to figure out how much" start="00:14:58.079" video="mainVideo" id=subtitle]]
+[[!template text="and how long nreverse takes" start="00:14:59.519" video="mainVideo" id=subtitle]]
+[[!template text="in this scenario." start="00:15:01.440" video="mainVideo" id=subtitle]]
+[[!template text="Or, we can take a function" start="00:15:03.839" video="mainVideo" id=subtitle]]
+[[!template text="which we have probably found" start="00:15:07.760" video="mainVideo" id=subtitle]]
+[[!template text="using one of the previous methods" start="00:15:10.880" video="mainVideo" id=subtitle]]
+[[!template text="which we anticipate that," start="00:15:12.880" video="mainVideo" id=subtitle]]
+[[!template text="as we understand, it takes a while," start="00:15:17.279" video="mainVideo" id=subtitle]]
+[[!template text="and annotate it with a benchmark-progn form," start="00:15:19.440" video="mainVideo" id=subtitle]]
+[[!template text="which... just execute the body" start="00:15:26.720" video="mainVideo" id=subtitle]]
+[[!template text="and report, each and every one of them," start="00:15:33.360" video="mainVideo" id=subtitle]]
+[[!template text="how long that body execution took." start="00:15:36.880" video="mainVideo" id=subtitle]]
+[[!template text="So for instance, here we added" start="00:15:41.360" video="mainVideo" id=subtitle]]
+[[!template text="a few message calls" start="00:15:45.360" video="mainVideo" id=subtitle]]
+[[!template text="inside those benchmark-progns," start="00:15:46.959" video="mainVideo" id=subtitle]]
+[[!template text="so we can see how long each part" start="00:15:49.040" video="mainVideo" id=subtitle]]
+[[!template text="of the function xref-matches-in-files" start="00:15:53.199" video="mainVideo" id=subtitle]]
+[[!template text="takes when it is run." start="00:16:03.600" video="mainVideo" id=subtitle]]
+[[!template text="Let's try it. Let's first call" start="00:16:06.320" video="mainVideo" id=subtitle]]
+[[!template text="emacs-lisp-byte-compile-and-load," start="00:16:11.839" video="mainVideo" id=subtitle]]
+[[!template text="so that we're sure that we are running" start="00:16:17.199" video="mainVideo" id=subtitle]]
+[[!template text="the fastest possible version of this code," start="00:16:20.720" video="mainVideo" id=subtitle]]
+[[!template text="so when we do find the bottlenecks," start="00:16:24.079" video="mainVideo" id=subtitle]]
+[[!template text="we are sure that they are real" start="00:16:29.519" video="mainVideo" id=subtitle]]
+[[!template text="and not because of the uncompiled code," start="00:16:31.279" video="mainVideo" id=subtitle]]
+[[!template text="macro expansion, or the lack of" start="00:16:36.240" video="mainVideo" id=subtitle]]
+[[!template text="some substitutions, other substitutions" start="00:16:43.519" video="mainVideo" id=subtitle]]
+[[!template text="that our code is relying on" start="00:16:46.160" video="mainVideo" id=subtitle]]
+[[!template text="but which might not be available" start="00:16:50.800" video="mainVideo" id=subtitle]]
+[[!template text="in the interpreter mode" start="00:17:01.279" video="mainVideo" id=subtitle]]
+[[!template text="just in the compiled code." start="00:17:03.279" video="mainVideo" id=subtitle]]
+[[!template text="Let's run." start="00:17:07.039" video="mainVideo" id=subtitle]]
+[[!template text="So we have this list," start="00:17:10.160" video="mainVideo" id=subtitle]]
+[[!template text="search for list," start="00:17:14.880" video="mainVideo" id=subtitle]]
+[[!template text="and the remaining time is spent during" start="00:17:26.160" video="mainVideo" id=subtitle]]
+[[!template text="printing of the results, which we didn't" start="00:17:29.760" video="mainVideo" id=subtitle]]
+[[!template text="annotate with the benchmarking macro," start="00:17:36.720" video="mainVideo" id=subtitle]]
+[[!template text="but it's still there." start="00:17:38.320" video="mainVideo" id=subtitle]]
+[[!template text="So we can see by switching to the" start="00:17:41.280" video="mainVideo" id=subtitle]]
+[[!template text="*Messages* buffer, C-h e," start="00:17:43.679" video="mainVideo" id=subtitle]]
+[[!template text="that unquoting was very fast." start="00:17:49.919" video="mainVideo" id=subtitle]]
+[[!template text="So the search took 400 milliseconds." start="00:17:52.080" video="mainVideo" id=subtitle]]
+[[!template text="It's slower than it would be" start="00:17:59.280" video="mainVideo" id=subtitle]]
+[[!template text="without the video being recorded, as well" start="00:18:02.480" video="mainVideo" id=subtitle]]
+[[!template text="as the rest of the measurements here." start="00:18:06.080" video="mainVideo" id=subtitle]]
+[[!template text="So the parsing of the results took more" start="00:18:09.039" video="mainVideo" id=subtitle]]
+[[!template text="than that, and the object allocation" start="00:18:12.160" video="mainVideo" id=subtitle]]
+[[!template text="took even more, which is unfortunate" start="00:18:16.559" video="mainVideo" id=subtitle]]
+[[!template text="but it's the reality" start="00:18:21.919" video="mainVideo" id=subtitle]]
+[[!template text="when we're dealing with a lot of" start="00:18:23.919" video="mainVideo" id=subtitle]]
+[[!template text="search results, because, well," start="00:18:26.400" video="mainVideo" id=subtitle]]
+[[!template text="Emacs Lisp is slower than grep." start="00:18:29.840" video="mainVideo" id=subtitle]]
+[[!template text="That's just a given." start="00:18:34.559" video="mainVideo" id=subtitle]]
+[[!template text="What can be done and what had been done" start="00:18:49.200" video="mainVideo" id=subtitle]]
+[[!template text="to improve on this?" start="00:18:54.400" video="mainVideo" id=subtitle]]
+[[!template text="Well, first of all," start="00:18:57.120" video="mainVideo" id=subtitle]]
+[[!template text="let's change the question," start="00:19:04.240" video="mainVideo" id=subtitle]]
+[[!template text="because this is more of" start="00:19:06.000" video="mainVideo" id=subtitle]]
+[[!template text="a retrospective sort of talk" start="00:19:07.360" video="mainVideo" id=subtitle]]
+[[!template text="rather than talking about future plans." start="00:19:09.760" video="mainVideo" id=subtitle]]
+[[!template new="1" text="What can one do to improve performance?" start="00:19:13.440" video="mainVideo" id=subtitle]]
+[[!template text="Well, basically, two things:" start="00:19:19.679" video="mainVideo" id=subtitle]]
+[[!template text="first, you try to make sure" start="00:19:24.160" video="mainVideo" id=subtitle]]
+[[!template text="that you're writing less code," start="00:19:27.919" video="mainVideo" id=subtitle]]
+[[!template text="then your code does fewer things," start="00:19:30.559" video="mainVideo" id=subtitle]]
+[[!template text="Fewer iterations of your operations." start="00:19:37.200" video="mainVideo" id=subtitle]]
+[[!template text="Basically, it's the realm" start="00:19:40.400" video="mainVideo" id=subtitle]]
+[[!template text="of choosing your algorithm well." start="00:19:42.000" video="mainVideo" id=subtitle]]
+[[!template text="But make sure it's as little complexity" start="00:19:46.880" video="mainVideo" id=subtitle]]
+[[!template text="as you can manage reasonably." start="00:19:54.880" video="mainVideo" id=subtitle]]
+[[!template new="1" text="Another is to try to reduce memory allocations." start="00:20:00.240" video="mainVideo" id=subtitle]]
+[[!template text="It's creating conses, the links of the list," start="00:20:05.760" video="mainVideo" id=subtitle]]
+[[!template text="of the lists. If you are mapping through" start="00:20:13.760" video="mainVideo" id=subtitle]]
+[[!template text="a list, creating a new one," start="00:20:17.919" video="mainVideo" id=subtitle]]
+[[!template text="you are creating conses." start="00:20:19.200" video="mainVideo" id=subtitle]]
+[[!template text="New objects in memory, anyway." start="00:20:22.640" video="mainVideo" id=subtitle]]
+[[!template text="And also, when you call string operations" start="00:20:26.159" video="mainVideo" id=subtitle]]
+[[!template text="like substring, when you create new strings," start="00:20:30.480" video="mainVideo" id=subtitle]]
+[[!template text="that's also what you do." start="00:20:33.679" video="mainVideo" id=subtitle]]
+[[!template text="When you allocate new memory," start="00:20:36.640" video="mainVideo" id=subtitle]]
+[[!template text="that triggers garbage collections later," start="00:20:39.200" video="mainVideo" id=subtitle]]
+[[!template text="which affect the performance of your code" start="00:20:43.600" video="mainVideo" id=subtitle]]
+[[!template text="quite severely. I have found that actually," start="00:20:49.200" video="mainVideo" id=subtitle]]
+[[!template text="contrary to my personal intuition," start="00:21:01.600" video="mainVideo" id=subtitle]]
+[[!template text="when you try to fine-tune the code" start="00:21:04.960" video="mainVideo" id=subtitle]]
+[[!template text="working on long lists of elements," start="00:21:08.240" video="mainVideo" id=subtitle]]
+[[!template text="long, long collection, large collections," start="00:21:13.120" video="mainVideo" id=subtitle]]
+[[!template text="it's even more important to try to avoid" start="00:21:15.520" video="mainVideo" id=subtitle]]
+[[!template text="or reduce memory allocations" start="00:21:20.159" video="mainVideo" id=subtitle]]
+[[!template text="rather than try to ensure" start="00:21:23.200" video="mainVideo" id=subtitle]]
+[[!template text="that less code is running," start="00:21:26.400" video="mainVideo" id=subtitle]]
+[[!template text="less operations are performed," start="00:21:32.240" video="mainVideo" id=subtitle]]
+[[!template text="because the garbage collector" start="00:21:34.960" video="mainVideo" id=subtitle]]
+[[!template text="can hit you in the posterior quite suddenly" start="00:21:38.080" video="mainVideo" id=subtitle]]
+[[!template text="that you will not always..." start="00:21:44.799" video="mainVideo" id=subtitle]]
+[[!template text="When you measure the input impact," start="00:21:49.520" video="mainVideo" id=subtitle]]
+[[!template text="you might not always measure the whole of it." start="00:21:51.760" video="mainVideo" id=subtitle]]
+[[!template text="And sometimes even when you have" start="00:21:56.799" video="mainVideo" id=subtitle]]
+[[!template text="a few operations, you can measure" start="00:22:02.640" video="mainVideo" id=subtitle]]
+[[!template text="all three of them, but at some point," start="00:22:06.559" video="mainVideo" id=subtitle]]
+[[!template text="if you just reduce a lot," start="00:22:09.520" video="mainVideo" id=subtitle]]
+[[!template text="remove most of the allocations," start="00:22:11.919" video="mainVideo" id=subtitle]]
+[[!template text="all three of them, the improvement" start="00:22:14.720" video="mainVideo" id=subtitle]]
+[[!template text="might be even bigger than the total" start="00:22:16.799" video="mainVideo" id=subtitle]]
+[[!template text="of three improvements" start="00:22:21.520" video="mainVideo" id=subtitle]]
+[[!template text="which you might have measured previously," start="00:22:23.440" video="mainVideo" id=subtitle]]
+[[!template text="like separately." start="00:22:27.200" video="mainVideo" id=subtitle]]
+[[!template text="So it's something to be on the lookout for," start="00:22:29.679" video="mainVideo" id=subtitle]]
+[[!template text="but of course, when you pick the algorithm," start="00:22:33.039" video="mainVideo" id=subtitle]]
+[[!template text="it's important not to do" start="00:22:39.520" video="mainVideo" id=subtitle]]
+[[!template text="more operations than you have to." start="00:22:45.200" video="mainVideo" id=subtitle]]
+[[!template new="1" text="We have examples of both" start="00:22:52.159" video="mainVideo" id=subtitle]]
+[[!template text="in the recent changes" start="00:22:56.000" video="mainVideo" id=subtitle]]
+[[!template text="to the xref and project packages," start="00:22:58.720" video="mainVideo" id=subtitle]]
+[[!template text="which we can examine here." start="00:23:02.559" video="mainVideo" id=subtitle]]
+[[!template text="Let's take a look at this one." start="00:23:06.960" video="mainVideo" id=subtitle]]
+[[!template text="This commit message lies a little bit" start="00:23:11.200" video="mainVideo" id=subtitle]]
+[[!template text="because it's referring to" start="00:23:14.880" video="mainVideo" id=subtitle]]
+[[!template text="the use of assoc instead of cl-assoc," start="00:23:19.039" video="mainVideo" id=subtitle]]
+[[!template text="and the actual change incorporates that," start="00:23:24.559" video="mainVideo" id=subtitle]]
+[[!template text="but it also incorporates" start="00:23:29.919" video="mainVideo" id=subtitle]]
+[[!template text="the second part of the sentence" start="00:23:33.440" video="mainVideo" id=subtitle]]
+[[!template text="which actually replaced" start="00:23:39.440" video="mainVideo" id=subtitle]]
+[[!template text="the use of assoc in there." start="00:23:41.360" video="mainVideo" id=subtitle]]
+[[!template text="Curiously, cl-assoc was pretty slow" start="00:23:46.960" video="mainVideo" id=subtitle]]
+[[!template text="because not only it created" start="00:23:50.480" video="mainVideo" id=subtitle]]
+[[!template text="quadratic complexity in the operation" start="00:23:52.559" video="mainVideo" id=subtitle]]
+[[!template text="and it was also calling" start="00:23:57.919" video="mainVideo" id=subtitle]]
+[[!template text="the Lisp function equal" start="00:23:59.919" video="mainVideo" id=subtitle]]
+[[!template text="for every iteration," start="00:24:02.880" video="mainVideo" id=subtitle]]
+[[!template text="whereas if we just use assoc there," start="00:24:04.400" video="mainVideo" id=subtitle]]
+[[!template text="which was the first version" start="00:24:08.880" video="mainVideo" id=subtitle]]
+[[!template text="of this change, of the improvement," start="00:24:10.080" video="mainVideo" id=subtitle]]
+[[!template text="it became already much faster," start="00:24:13.919" video="mainVideo" id=subtitle]]
+[[!template text="but then switching to a hash table" start="00:24:15.760" video="mainVideo" id=subtitle]]
+[[!template text="which turned this lookup" start="00:24:20.640" video="mainVideo" id=subtitle]]
+[[!template text="from O(n) complexity" start="00:24:28.080" video="mainVideo" id=subtitle]]
+[[!template text="into, well, amortized constant one," start="00:24:31.760" video="mainVideo" id=subtitle]]
+[[!template text="even better." start="00:24:35.600" video="mainVideo" id=subtitle]]
+[[!template text="So, use hash tables, kids." start="00:24:37.600" video="mainVideo" id=subtitle]]
+[[!template text="Another commit here is about using" start="00:24:45.679" video="mainVideo" id=subtitle]]
+[[!template text="the inhibit-modification-hooks." start="00:24:52.400" video="mainVideo" id=subtitle]]
+[[!template text="So, turns out when you're printing" start="00:24:55.520" video="mainVideo" id=subtitle]]
+[[!template text="into a buffer, even if you have already" start="00:24:58.000" video="mainVideo" id=subtitle]]
+[[!template text="disabled the undo history," start="00:25:01.679" video="mainVideo" id=subtitle]]
+[[!template text="binding this variable to" start="00:25:06.159" video="mainVideo" id=subtitle]]
+[[!template text="a non-null value is pretty good" start="00:25:08.480" video="mainVideo" id=subtitle]]
+[[!template text="because you are able to avoid running" start="00:25:10.880" video="mainVideo" id=subtitle]]
+[[!template text="a number of hooks, which improves performance." start="00:25:15.520" video="mainVideo" id=subtitle]]
+[[!template text="Next. This one was about moving the" start="00:25:21.120" video="mainVideo" id=subtitle]]
+[[!template text="file-remote-p call" start="00:25:28.640" video="mainVideo" id=subtitle]]
+[[!template text="from inside the loop." start="00:25:32.000" video="mainVideo" id=subtitle]]
+[[!template text="This function is actually" start="00:25:37.279" video="mainVideo" id=subtitle]]
+[[!template text="surprisingly slow-ish for the goal," start="00:25:42.039" video="mainVideo" id=subtitle]]
+[[!template text="for its purpose, so you don't really want" start="00:25:49.039" video="mainVideo" id=subtitle]]
+[[!template text="to call it on every file name in the list" start="00:25:52.000" video="mainVideo" id=subtitle]]
+[[!template text="when you have a lot of them," start="00:25:56.159" video="mainVideo" id=subtitle]]
+[[!template text="and especially if your code" start="00:25:59.520" video="mainVideo" id=subtitle]]
+[[!template text="is running in a buffer" start="00:26:02.000" video="mainVideo" id=subtitle]]
+[[!template text="visiting a remote file, like through TRAMP." start="00:26:04.640" video="mainVideo" id=subtitle]]
+[[!template text="You might end up trying to" start="00:26:10.640" video="mainVideo" id=subtitle]]
+[[!template text="devise different approaches" start="00:26:15.120" video="mainVideo" id=subtitle]]
+[[!template text="to avoid checking whether" start="00:26:16.880" video="mainVideo" id=subtitle]]
+[[!template text="every file name is remote" start="00:26:20.159" video="mainVideo" id=subtitle]]
+[[!template text="if you're dealing with a list of file names," start="00:26:23.279" video="mainVideo" id=subtitle]]
+[[!template text="so this one, take a look, be careful with it." start="00:26:25.360" video="mainVideo" id=subtitle]]
+[[!template text="A similar, slower function, with-current-buffer," start="00:26:34.640" video="mainVideo" id=subtitle]]
+[[!template text="but not so much. So it all depends on" start="00:26:43.120" video="mainVideo" id=subtitle]]
+[[!template text="really how often you call it." start="00:26:46.880" video="mainVideo" id=subtitle]]
+[[!template text="Sometimes you might want to" start="00:26:48.400" video="mainVideo" id=subtitle]]
+[[!template text="rewrite your code so that" start="00:26:51.279" video="mainVideo" id=subtitle]]
+[[!template text="it's called less often." start="00:26:52.720" video="mainVideo" id=subtitle]]
+[[!template text="And expand-file-name, which hits the disk." start="00:26:54.720" video="mainVideo" id=subtitle]]
+[[!template text="So if you're dealing with file names," start="00:26:59.760" video="mainVideo" id=subtitle]]
+[[!template text="you might want to replace it" start="00:27:01.200" video="mainVideo" id=subtitle]]
+[[!template text="with concatenation at certain points." start="00:27:02.960" video="mainVideo" id=subtitle]]
+[[!template text="Okay, back to these changes later." start="00:27:07.520" video="mainVideo" id=subtitle]]
+[[!template text="This one just removed a location of a cons" start="00:27:22.159" video="mainVideo" id=subtitle]]
+[[!template text="per match hit, and still it brought 5%" start="00:27:28.480" video="mainVideo" id=subtitle]]
+[[!template text="or something like that improvement" start="00:27:33.679" video="mainVideo" id=subtitle]]
+[[!template text="to the whole command." start="00:27:37.039" video="mainVideo" id=subtitle]]
+[[!template text="So that's a pretty significant improvement" start="00:27:41.120" video="mainVideo" id=subtitle]]
+[[!template text="for a small change like that." start="00:27:46.000" video="mainVideo" id=subtitle]]
+[[!template text="Similarly, here we just made sure" start="00:27:53.600" video="mainVideo" id=subtitle]]
+[[!template text="to avoid a splits... no, a substring call," start="00:28:01.679" video="mainVideo" id=subtitle]]
+[[!template text="and probably an allocation of the whole" start="00:28:09.520" video="mainVideo" id=subtitle]]
+[[!template text="buffer string, but in my testing," start="00:28:12.399" video="mainVideo" id=subtitle]]
+[[!template text="that doesn't actually matter much," start="00:28:16.320" video="mainVideo" id=subtitle]]
+[[!template text="at least so much, but a substring call" start="00:28:19.440" video="mainVideo" id=subtitle]]
+[[!template text="per result... If we see," start="00:28:22.399" video="mainVideo" id=subtitle]]
+[[!template text="since we changed to manual parsing" start="00:28:28.960" video="mainVideo" id=subtitle]]
+[[!template text="of the buffer, with the strings" start="00:28:33.039" video="mainVideo" id=subtitle]]
+[[!template text="delimited with zero bytes," start="00:28:37.440" video="mainVideo" id=subtitle]]
+[[!template text="it gave an overall improvement" start="00:28:41.440" video="mainVideo" id=subtitle]]
+[[!template text="of 20%, again on my machine" start="00:28:43.840" video="mainVideo" id=subtitle]]
+[[!template text="with a pretty fast SSD," start="00:28:47.440" video="mainVideo" id=subtitle]]
+[[!template text="and with a warm disk cache, of course." start="00:28:50.720" video="mainVideo" id=subtitle]]
+[[!template text="But still... Going back to this revision," start="00:28:53.679" video="mainVideo" id=subtitle]]
+[[!template text="it was actually quite surprising" start="00:29:05.360" video="mainVideo" id=subtitle]]
+[[!template text="that migration to a cl-defstruct" start="00:29:09.440" video="mainVideo" id=subtitle]]
+[[!template text="from eieio, the Common Lisp-inspired" start="00:29:15.200" video="mainVideo" id=subtitle]]
+[[!template text="object system first introduced" start="00:29:24.080" video="mainVideo" id=subtitle]]
+[[!template text="in the CEDET tools," start="00:29:26.480" video="mainVideo" id=subtitle]]
+[[!template text="that was a bit of a surprise," start="00:29:34.240" video="mainVideo" id=subtitle]]
+[[!template text="because not much of my" start="00:29:39.360" video="mainVideo" id=subtitle]]
+[[!template text="benchmark benchmarking" start="00:29:44.799" video="mainVideo" id=subtitle]]
+[[!template text="actually pointed at it being the problem." start="00:29:46.080" video="mainVideo" id=subtitle]]
+[[!template text="Probably because the accessors" start="00:29:50.960" video="mainVideo" id=subtitle]]
+[[!template text="were not the actual problem," start="00:29:55.760" video="mainVideo" id=subtitle]]
+[[!template text="like the oref macros" start="00:29:57.520" video="mainVideo" id=subtitle]]
+[[!template text="and the code accessing the slots," start="00:30:00.399" video="mainVideo" id=subtitle]]
+[[!template text="but the construction," start="00:30:06.960" video="mainVideo" id=subtitle]]
+[[!template text="the object construction code," start="00:30:10.720" video="mainVideo" id=subtitle]]
+[[!template text="that was where most of the time" start="00:30:14.320" video="mainVideo" id=subtitle]]
+[[!template text="was spent unnecessarily," start="00:30:16.559" video="mainVideo" id=subtitle]]
+[[!template text="maybe doing type-checking," start="00:30:21.200" video="mainVideo" id=subtitle]]
+[[!template text="maybe some other stuff." start="00:30:24.240" video="mainVideo" id=subtitle]]
+[[!template text="So if you have lots of values," start="00:30:28.880" video="mainVideo" id=subtitle]]
+[[!template text="you need to treat like objects in... and" start="00:30:36.080" video="mainVideo" id=subtitle]]
+[[!template text="virtual dispatch on them in your package," start="00:30:39.120" video="mainVideo" id=subtitle]]
+[[!template text="you might want to look into" start="00:30:42.000" video="mainVideo" id=subtitle]]
+[[!template text="cl-defstruct for them." start="00:30:45.200" video="mainVideo" id=subtitle]]
+[[!template new="1" text="Going on to the next section," start="00:30:52.240" video="mainVideo" id=subtitle]]
+[[!template text="I have prepared the sort of comparison" start="00:30:54.080" video="mainVideo" id=subtitle]]
+[[!template text="between cl-lib, dash, and seq," start="00:31:01.200" video="mainVideo" id=subtitle]]
+[[!template text="the collection libraries we have" start="00:31:05.519" video="mainVideo" id=subtitle]]
+[[!template text="available for us in Emacs." start="00:31:09.360" video="mainVideo" id=subtitle]]
+[[!template text="That is the popular ones," start="00:31:11.279" video="mainVideo" id=subtitle]]
+[[!template text="but since I'm running behind on time," start="00:31:15.760" video="mainVideo" id=subtitle]]
+[[!template text="I'll probably just summarize the findings." start="00:31:21.440" video="mainVideo" id=subtitle]]
+[[!template text="First of all, seq is nice." start="00:31:27.760" video="mainVideo" id=subtitle]]
+[[!template text="Its generic approach is probably" start="00:31:31.919" video="mainVideo" id=subtitle]]
+[[!template text="quite decent for most of the situations," start="00:31:38.480" video="mainVideo" id=subtitle]]
+[[!template text="but there are places where it could be" start="00:31:41.919" video="mainVideo" id=subtitle]]
+[[!template text="optimized better, so instead of having" start="00:31:49.840" video="mainVideo" id=subtitle]]
+[[!template text="quadratic performance, it could use a" start="00:31:53.679" video="mainVideo" id=subtitle]]
+[[!template text="hash table, like for instance," start="00:31:56.399" video="mainVideo" id=subtitle]]
+[[!template text="dash does here--" start="00:31:59.200" video="mainVideo" id=subtitle]]
+[[!template text="in dash, union or delete-dups" start="00:32:02.000" video="mainVideo" id=subtitle]]
+[[!template text="does in its implementation." start="00:32:06.240" video="mainVideo" id=subtitle]]
+[[!template text="The dash itself is curiously fast," start="00:32:12.960" video="mainVideo" id=subtitle]]
+[[!template text="at least faster than I might have expected," start="00:32:16.640" video="mainVideo" id=subtitle]]
+[[!template text="possibly because of" start="00:32:20.000" video="mainVideo" id=subtitle]]
+[[!template text="the implementation approach" start="00:32:21.600" video="mainVideo" id=subtitle]]
+[[!template text="where it uses code generation" start="00:32:25.120" video="mainVideo" id=subtitle]]
+[[!template text="to avoid function calls," start="00:32:33.200" video="mainVideo" id=subtitle]]
+[[!template text="at least some of them," start="00:32:35.840" video="mainVideo" id=subtitle]]
+[[!template text="which is interesting." start="00:32:37.840" video="mainVideo" id=subtitle]]
+[[!template text="But since both seq and dash" start="00:32:41.120" video="mainVideo" id=subtitle]]
+[[!template text="avoid mutations--they don't really have" start="00:32:45.600" video="mainVideo" id=subtitle]]
+[[!template text="mutating counterparts to common functions" start="00:32:49.919" video="mainVideo" id=subtitle]]
+[[!template text="like you have with cl-remove-if, cl-delete-if," start="00:32:52.399" video="mainVideo" id=subtitle]]
+[[!template text="or just cl-remove, cl-delete," start="00:32:56.480" video="mainVideo" id=subtitle]]
+[[!template text="it still can be valuable to look into" start="00:33:02.000" video="mainVideo" id=subtitle]]
+[[!template text="destructive versions of those functions," start="00:33:08.000" video="mainVideo" id=subtitle]]
+[[!template text="something from the core library" start="00:33:12.240" video="mainVideo" id=subtitle]]
+[[!template text="like delete-dups or nreverse," start="00:33:16.880" video="mainVideo" id=subtitle]]
+[[!template text="for your code when you're really trying" start="00:33:22.559" video="mainVideo" id=subtitle]]
+[[!template text="to get as close to the metal" start="00:33:24.399" video="mainVideo" id=subtitle]]
+[[!template text="or whatever as you can," start="00:33:29.519" video="mainVideo" id=subtitle]]
+[[!template text="because avoiding extra allocations," start="00:33:34.320" video="mainVideo" id=subtitle]]
+[[!template text="it can really be useful." start="00:33:40.080" video="mainVideo" id=subtitle]]
+[[!template text="You can really improve their performance" start="00:33:43.200" video="mainVideo" id=subtitle]]
+[[!template text="if you don't do a lot of other stuff." start="00:33:46.159" video="mainVideo" id=subtitle]]
+[[!template text="delete-consecutive-dups is blazing faster." start="00:33:54.080" video="mainVideo" id=subtitle]]
+[[!template text="It only requires pre-sorted strings." start="00:34:00.080" video="mainVideo" id=subtitle]]
+[[!template text="What else to say..." start="00:34:03.919" video="mainVideo" id=subtitle]]
+[[!template text="If you are going to read these measurements," start="00:34:08.399" video="mainVideo" id=subtitle]]
+[[!template text="make sure to keep in mind" start="00:34:13.200" video="mainVideo" id=subtitle]]
+[[!template text="that reverse is not free," start="00:34:15.359" video="mainVideo" id=subtitle]]
+[[!template text="so for instance, if we're looking" start="00:34:18.000" video="mainVideo" id=subtitle]]
+[[!template text="at this comparison" start="00:34:20.240" video="mainVideo" id=subtitle]]
+[[!template text="between remove and delete, for instance," start="00:34:22.480" video="mainVideo" id=subtitle]]
+[[!template text="they're using reverse" start="00:34:26.399" video="mainVideo" id=subtitle]]
+[[!template text="to avoid modifying the data," start="00:34:27.919" video="mainVideo" id=subtitle]]
+[[!template text="the sample data, so we don't have to" start="00:34:32.159" video="mainVideo" id=subtitle]]
+[[!template text="create it every time." start="00:34:34.800" video="mainVideo" id=subtitle]]
+[[!template text="But to compare how much faster" start="00:34:36.720" video="mainVideo" id=subtitle]]
+[[!template text="delete is than remove," start="00:34:41.919" video="mainVideo" id=subtitle]]
+[[!template text="we need to subtract 787 milliseconds" start="00:34:43.760" video="mainVideo" id=subtitle]]
+[[!template text="from here and from here" start="00:34:50.800" video="mainVideo" id=subtitle]]
+[[!template text="so it comes out to like 230 milliseconds" start="00:34:52.320" video="mainVideo" id=subtitle]]
+[[!template text="in this example, the last example," start="00:34:58.480" video="mainVideo" id=subtitle]]
+[[!template text="and 100 to 1 second, 250 milliseconds here," start="00:35:02.560" video="mainVideo" id=subtitle]]
+[[!template text="so the difference is 5-fold here." start="00:35:12.000" video="mainVideo" id=subtitle]]
+[[!template text="Not 2-fold." start="00:35:17.599" video="mainVideo" id=subtitle]]
+[[!template text="All right. With this, I'm going to" start="00:35:20.160" video="mainVideo" id=subtitle]]
+[[!template text="thank you for listening, for watching" start="00:35:26.480" video="mainVideo" id=subtitle]]
+[[!template text="and I'll be taking questions." start="00:35:29.520" video="mainVideo" id=subtitle]]
+[[!template text="Thank you." start="00:35:31.920" video="mainVideo" id=subtitle]]
+[[!template text="captions by sachac" start="00:35:32.920" video="mainVideo" id=subtitle]]