summaryrefslogtreecommitdiffstats
path: root/2021/captions/faster.md
blob: be9b5083d4bfd708dcc07d3182a1e8d5d1d72da4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
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]]