December 06, 2019
1.9k

# Fast by Default: Algorithmic Optimization in Practice (dotJS 2019)

December 06, 2019

## Transcript

3. ### Leaﬂet earcut pixelmatch delaunator rbush ﬂatbush kdbush geokdbush geoﬂatbush geojson-vt

potpack supercluster martini delatin cheap-ruler polylabel icomesh concaveman dobbyscan linematch lineclip simplify-js robust-predicates tinyqueue ﬂatqueue which-polygon quickselect webgl-wind suncalc ﬂamebearer tiny-sdf simpleheat … github.com/mourner/projects

9. ### delaunay: 150s delaunay-fast: 117s faster-delaunay: 5s delaunator: 1s delaunator-cpp: 0.9s

delaunator-rs: 0.9s Delaunay triangulation of 1 million points in JavaScript:
10. ### 1. ﬁnd a bottleneck 2. ﬁnd out why it’s slow

3. make it faster optimization:
11. ### 1. ﬁnd a bottleneck 2. ﬁnd out why it’s slow

3. make it faster optimization: algorithm s!

15. ### rollup/rollup#2062 rollup: map = magicString.generateMap() magic-string: ... map = encode(obj)

rollup: obj = decode(map)

17. ### rollup/rollup#2062 rollup: map = magicString.generateDecodedMap() magic-string: map = encode(obj) rollup:

obj = decode(map) source maps got 40% faster

size

21. ### for (const item of array) { sum += item; }

O(n) — suspicious
22. ### O(n2) — ridiculously slow for (let i = 0, n

= array.length; i < n; i++) { for (let j = i + 1; j < n; j++) { sum += array[i] + array[j]; } }
23. ### function foo(array) { for (const item of array) { array[array.indexOf(item)]

= item + 10; } } O(n2) — ridiculously slow
24. ### function foo(array) { for (const item of array) { bar(array,

item); } } function bar(array, item) { array[array.indexOf(item)] = item + 10; } O(n2) — ridiculously slow

26. ### O(n3) — rewrite from scratch for (let i = 0,

n = array.length; i < n; i++) { for (let j = i + 1; j < n; j++) { for (let k = j + 1; k < n; k++) { sum += array[i] + array[j]; } } }
27. ### if (j < 0) { if (triangles.length === 0) triangles.push([i]);

return; } for (let n = triangles.length, a = 0; a < n; ++a) { let sa = triangles[a]; if (sa[0] === j) { for (let b = a + 1; b < n; ++b) { let sb = triangles[b]; if (sb[sb.length - 1] === i) { triangles.splice(b, 1); triangles[a] = sa = sb.concat(sa); return; } } sa.unshift(i); return; } d3/d3-delaunay#23
28. ### array.indexOf array.lastIndexOf array.splice array.includes array.reverse array.every Object.values array.ﬁnd array.some array.ﬁndIndex

array.reduce array.reduceRight array.some Object.keys O(n) — suspicious

(4 times)

y] = foo();
32. ### const lines = input.split(';'); for (const line of lines) {

const segments = line.split(','); for (const segment of segments) { const decoded = decode(segment); for (const i of decoded) { ... } } } Rich-Harris/sourcemap-codec#71
33. ### for (let i = 0; i < input.length; i++) {

const c = input.charCodeAt(i); if (c === 44) { // "," ... } else if (c === 59) { // ";" ... Rich-Harris/sourcemap-codec#71 3 times faster

39. ### 1. O(n) → O(log n) 2. O(n log n) →

O(n) 3. O(n2) → O(n log n) 4. O(n3) — throw out algorithmic optimization

42. ### algorithmic optimization: do more at the beginning to do less

every next time
43. ### • hash map • hash set • binary search tree

• priority heap • linked list • interval tree • r-tree • quadtree • kd-tree • … data structures

46. ### HashTable Array [10, 20, 30]; { '1': 10, '2': 20,

'3': 30 }; { '0': 10, '1': 20, ‘2': 30 };
47. ### istanbuljs/istanbul-lib-instrument#22 { '1': 10, '2': 20, '3': 30 }; 15

times faster { '0': 10, '1': 20, ‘2': 30 };

50. ### 1. learn how things work under the hood 2. don’t

be afraid to reinvent the wheel 3. simplify your code constantly 4. practice optimization, and you’ll learn how to write fast code by default