Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

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

Vladimir Agafonkin

December 06, 2019
Tweet

More Decks by Vladimir Agafonkin

Other Decks in Programming

Transcript

  1. Leaflet earcut pixelmatch delaunator rbush flatbush kdbush geokdbush geoflatbush geojson-vt

    potpack supercluster martini delatin cheap-ruler polylabel icomesh concaveman dobbyscan linematch lineclip simplify-js robust-predicates tinyqueue flatqueue which-polygon quickselect webgl-wind suncalc flamebearer tiny-sdf simpleheat … github.com/mourner/projects
  2. 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:
  3. 1. find a bottleneck 2. find out why it’s slow

    3. make it faster optimization:
  4. 1. find a bottleneck 2. find out why it’s slow

    3. make it faster optimization: algorithm s!
  5. 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]; } }
  6. 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
  7. 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]; } } }
  8. 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
  9. 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
  10. 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
  11. 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
  12. • hash map • hash set • binary search tree

    • priority heap • linked list • interval tree • r-tree • quadtree • kd-tree • … data structures
  13. HashTable Array [10, 20, 30]; { '1': 10, '2': 20,

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

    times faster { '0': 10, '1': 20, ‘2': 30 };
  15. 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