Slide 1

Slide 1 text

Vladimir Agafonkin ⚡Fast by default: everyday algorithmic thinking 2018

Slide 2

Slide 2 text

rain.in.ua

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

одержимый скоростью кода

Slide 8

Slide 8 text

❤❤❤ open source

Slide 9

Slide 9 text

1. Найти узкую задачу 2. ⚡ Создать для нее самую быструю и простую в мире JavaScript-библиотеку 3. Перейти к пункту №1

Slide 10

Slide 10 text

Leaflet, mapbox-gl-js, mapbox-gl-native, earcut, earcut.hpp, rbush, rbush-knn, kdbush, kdbush.hpp, geokdbush, flatbush, geoflatbush, concaveman, supercluster, supercluster.hpp, dobbyscan, delaunator, delaunator-rs, d3-delaunay, linematch, lineclip, pixelmatch, simplify-js, cheap-ruler, polylabel, tinyqueue, flatqueue, tile-cover, which-polygon, quickselect, simple-statistics, tiny-sdf, geojson-vt, potpack, geojson-vt-cpp, geobuf, pbf, tile- reduce, geojson.hpp, geometry.hpp, tile-decorator, mbtiles- extracts, webgl-wind, suncalc, flamebearer, simpleheat, binary-split, magic-string, polysnap, rollup, sourcemap-codec

Slide 11

Slide 11 text

github.com/mapbox/delaunator

Slide 12

Slide 12 text

github.com/d3/d3-delaunay

Slide 13

Slide 13 text

1.delaunay: 150s 2.delaunay-fast: 117s 3.faster-delaunay: 5s 4.delaunator: 1s⚡ 5.delaunator-cpp: 0.9s 6.delaunator-rs: 0.9s триангуляция 1 миллиона точек в JS

Slide 14

Slide 14 text

mapbox/earcut (JS) mapbox/earcut.hpp (C++)

Slide 15

Slide 15 text

пространственные индексы

Slide 16

Slide 16 text

github.com/mourner/rbush github.com/mourner/kdbush github.com/mourner/flatbush github.com/mourner/rbush-knn github.com/mourner/geokdbush github.com/mourner/geoflatbush

Slide 17

Slide 17 text

mapbox/supercluster (JS) mapbox/supercluter-hpp (C++)

Slide 18

Slide 18 text

mapbox/supercluster (JS) mapbox/supercluter-hpp (C++)

Slide 19

Slide 19 text

~ mapbox/geojson-vt (JS) mapbox/geojson-vt-cpp (C++)

Slide 20

Slide 20 text

github.com/mapbox/webgl-wind

Slide 21

Slide 21 text

github.com/mapbox/potpack

Slide 22

Slide 22 text

mapbox/pixelmatch (JS) mapbox/pixelmatch-cpp (C++)

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

математическое образование? %

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

В такой чудесный, светлый день Мне хочется писать стихами... Но, право, ведь порою лень Вы не желали обуздать и сами? Контрольная, смотрю, весьма сложна, И отвечать совсем уж неохота, Когда за окнами прекрасная весна, И о ассемблере не мыслиться чего-то...

Slide 27

Slide 27 text

Владимир Агафонкин Идиотское введение в алгоритмы 2018

Slide 28

Slide 28 text

зачем понимать алгоритмы?

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

99% проблем с быстродействием — алгоритмического характера

Slide 31

Slide 31 text

медленный код: код, выполняющий лишнюю работу

Slide 32

Slide 32 text

No content

Slide 33

Slide 33 text

алгоритмическое мышление: искусство отлынивать от лишней работы (в коде)

Slide 34

Slide 34 text

приложение фреймворки

Slide 35

Slide 35 text

No content

Slide 36

Slide 36 text

rollup/rollup#2062 rollup: map = magicString.generateMap() rollup: obj = decode(map)

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

rollup/rollup#2062 rollup: map = magicString.generateDecodedMap() magic-string: map = encode(obj) rollup: obj = decode(map) source map’ы на 40% быстрее

Slide 39

Slide 39 text

требует алгоритмического мышления 1. найти узкие места 2. выяснить, почему они медленные 3. оптимизировать оптимизация:

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

O(1) O(log n) O(n) O(n log n) O(n2) O(n3)

Slide 42

Slide 42 text

алгоритмическая сложность: (= понять, почему тормозит и что с этим делать) способ описать, как быстродействие меняется с размером данных

Slide 43

Slide 43 text

array[0] + array[1]; O(1) — моментально

Slide 44

Slide 44 text

O(n) — подозрительно for (const item of array) { sum += item; }

Slide 45

Slide 45 text

O(n2) — тормозное говно for (let i = 0, n = array.length; i < n; i++) { for (let j = i + 1; j < n; j++) { sum += array[i] + array[j]; } }

Slide 46

Slide 46 text

function foo(array) { for (const item of array) { array[array.indexOf(item)] = item + 10; } } O(n2) — тормозное говно

Slide 47

Slide 47 text

function foo(array) { for (const item of array) { bar(array, item); } } function bar(array, item) { array[array.indexOf(item)] = item + 10; } O(n2) — тормозное говно

Slide 48

Slide 48 text

accidentallyquadratic.tumblr.com

Slide 49

Slide 49 text

O(n3) — невыносимо, выкинуть нафиг 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]; } } }

Slide 50

Slide 50 text

1. O(1) — моментально 2. O(n) — подозрительно 3. O(n2) — тормозное говно 4. O(n3) — выкинуть нафиг

Slide 51

Slide 51 text

1. O(1) — 1 2. O(n) — 1000 3. O(n2) — 1,000,000 4. O(n3) — 1,000,000,000 (n = 1000)

Slide 52

Slide 52 text

чорти б мене побрали!!! хай йому грець!! дідько! 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

Slide 53

Slide 53 text

array.indexOf array.lastIndexOf array.splice array.includes array.reverse array.every Object.values array.find array.some array.findIndex array.reduce array.reduceRight array.some Object.keys O(n) — подозрительно

Slide 54

Slide 54 text

No content

Slide 55

Slide 55 text

array.slice array.concat array.map array.filter str.split подозрительные аллокации

Slide 56

Slide 56 text

a.slice().concat(b).map(foo) .filter(bar).reduce(bla, 0); выделить память и сразу выкинуть (4 раза)

Slide 57

Slide 57 text

for (const b of items) { a.slice().concat(b).map(foo) .filter(bar).reduce(bla, 0); } выделить память и сразу выкинуть (4 раза)

Slide 58

Slide 58 text

имьютабилити! реактивность! функциональное программирование! чертовы аллокации

Slide 59

Slide 59 text

JIT-оптимизатор в JS-движках не всегда понимает, чего вы хотите

Slide 60

Slide 60 text

пишите код максимально предсказуемо, чтобы движок поменьше угадывал

Slide 61

Slide 61 text

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) { ... } } }

Slide 62

Slide 62 text

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) { // ";" ... в три раза быстрее

Slide 63

Slide 63 text

No content

Slide 64

Slide 64 text

O(1) O(n) O(log n) O(log n) — очень быстро

Slide 65

Slide 65 text

1 1,000,000 20 O(log n) — очень быстро

Slide 66

Slide 66 text

бинарный поиск o(log n)

Slide 67

Slide 67 text

No content

Slide 68

Slide 68 text

No content

Slide 69

Slide 69 text

No content

Slide 70

Slide 70 text

No content

Slide 71

Slide 71 text

No content

Slide 72

Slide 72 text

No content

Slide 73

Slide 73 text

rollup/rollup#2228 … в 40 раз быстрее

Slide 74

Slide 74 text

1. O(n) → O(log n) 2. O(n log n) → O(n) 3. O(n2) → O(n log n) 4. O(n3) — выкинуть алгоритмическая оптимизация:

Slide 75

Slide 75 text

медленно медленно медленно алгоритмическая оптимизация:

Slide 76

Slide 76 text

организовать данные алгоритмическая оптимизация:

Slide 77

Slide 77 text

алгоритмическая оптимизация: сделать больше в начале, чтобы делать меньше каждый следующий раз

Slide 78

Slide 78 text

структуры данных: как организорвать данные для быстрого поиска и обновления

Slide 79

Slide 79 text

• hash map • hash set • binary search tree • priority heap • linked list • interval tree • grid • r-tree • quadtree • kd-tree структуры данных:

Slide 80

Slide 80 text

отсортированный массив o(n log n) ❤ любимая структура данных:

Slide 81

Slide 81 text

отсортировать вокруг элемента, чтобы все слева были меньше o(n) github.com/mourner/quickselect 39, 28, 28, 33, 21, 12, 22, 50, 53, 56, 59, 65, 90, 77, 95

Slide 82

Slide 82 text

github.com/mourner/kdbush

Slide 83

Slide 83 text

priority queue: push: o(1) top: o(1) pop: o(log n) github.com/mourner/tinyqueue github.com/mourner/flatqueue

Slide 84

Slide 84 text

{ '1': 10, '2': 20, '3': 30 }; { '0': 10, '1': 20, ‘2': 30 }; HashTable Array [10, 20, 30];

Slide 85

Slide 85 text

istanbuljs/istanbul-lib-instrument#22 { '1': 10, '2': 20, '3': 30 }; { '0': 10, '1': 20, ‘2': 30 }; в 15 раз быстрее

Slide 86

Slide 86 text

все необходимое уже изобрели до вас* *но реализовали через ж

Slide 87

Slide 87 text

как я читаю научные публикации и прилагаемый код

Slide 88

Slide 88 text

1. думайте, как оно работает 2. не бойтесь лезть в чужой код + 3. не бойтесь изобретать велосипеды 4. участвуйте в open source ❤ 5. постоянно упрощайте 6. практикуйте оптимизацию , и вы научитесь писать код, который сразу работает быстро

Slide 89

Slide 89 text

спасибо agafonkin.com