Fast by Default: Algorithmic Optimization in Practice (JSCamp 2019)

Fast by Default: Algorithmic Optimization in Practice (JSCamp 2019)

6d07e6d95a43357254698ce9723350e6?s=128

Vladimir Agafonkin

July 19, 2019
Tweet

Transcript

  1. 3.
  2. 4.
  3. 5.
  4. 6.
  5. 9.

    1.find a narrowly scoped task 2.⚡make the world’s fastest and

    simplest JavaScript library for it 3. repeat
  6. 10.

    Leaflet, mapbox-gl-js, mapbox-gl-native, earcut, earcut.hpp, pixelmatch, rbush, rbush-knn, kdbush, kdbush.hpp,

    geokdbush, flatbush, geoflatbush, concaveman, pbf, supercluster, supercluster.hpp, dobbyscan, delaunator, d3-delaunay, delaunator-rs, linematch, lineclip, geojson-vt, geojson-vt-cpp, potpack, simplify-js, cheap-ruler, polylabel, tinyqueue, flatqueue, tile-cover, which-polygon, quickselect, webgl-wind, suncalc, flamebearer, simple-statistics, tiny-sdf, geobuf, tile-reduce, geojson.hpp, geometry.hpp, tile-decorator, mbtiles-extracts, simpleheat, road-orientation-map, rollup, magic-string, sourcemap-codec, binary-split
  7. 19.
  8. 24.
  9. 27.
  10. 28.

    1. find a bottleneck 2. find out why it’s slow

    3. make it faster optimization:
  11. 29.
  12. 30.

    1. find a bottleneck 2. find out why it’s slow

    3. make it faster optimization:
  13. 32.
  14. 33.
  15. 41.

    1. O(1) — 1 2. O(n) — 1000 3. O(n2)

    — 1,000,000 4. O(n3) — 1,000,000,000 (n = 1000)
  16. 44.

    O(n2) — terribly slow for (let i = 0, n

    = array.length; i < n; i++) { for (let j = i + 1; j < n; j++) { sum += array[i] + array[j]; } }
  17. 46.

    function foo(array) { for (const item of array) { bar(array,

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

    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]; } } }
  19. 49.

    1. O(1) — instant 2. O(n) — suspicious 3. O(n2)

    — terribly slow 4. O(n3) — throw out
  20. 50.

    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
  21. 52.
  22. 58.

    Rich-Harris/sourcemap-codec#71 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) { ... } } }
  23. 59.

    Rich-Harris/sourcemap-codec#71 for (let i = 0; i < input.length; i++)

    { const c = input.charCodeAt(i); if (c === 44) { // "," ... } else if (c === 59) { // ";" ... 3 times faster
  24. 64.
  25. 65.
  26. 66.
  27. 67.
  28. 68.
  29. 69.
  30. 71.

    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
  31. 75.

    • hash map • hash set • binary search tree

    • priority heap • linked list • interval tree • grid • r-tree • quadtree • kd-tree data structures
  32. 77.

    sort so that all items in the left are smaller

    o(n) github.com/mourner/quickselect 39, 28, 28, 33, 21, 12, 22, 50, 53, 56, 59, 65, 90, 77, 95
  33. 80.

    { '1': 10, '2': 20, '3': 30 }; { '0':

    10, '1': 20, ‘2': 30 }; HashTable Array [10, 20, 30];
  34. 81.

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

    '0': 10, '1': 20, ‘2': 30 }; 15 times faster
  35. 84.

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

    hesitate to dig inside frameworks 3. contribute to open source 4. don’t be afraid to reinvent the wheel 5. simplify your code constantly 6. practice optimization, and you’ll learn how to write fast code from the start