Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Владимир Агафонкин
⚡Быстро по умолчанию: 

алгоритмическое мышление на практике
rain.in.ua
одержимый
скоростью кода
❤❤❤
open source
1. 🌱 Найти узкую задачу
2. ⚡ Создать для нее самую быструю и
простую в мире JavaScript-библиотеку
3. 🔄 Перейти к пункту №1
Leaflet, mapbox-gl-js, mapbox-gl-native, earcut, earcut.hpp,
rbush, rbush-knn, kdbush, kdbush.hpp, geokdbush,
flatbush, geofl...
github.com/mapbox/delaunator
github.com/d3/d3-delaunay
1. delaunay: 150s
2. delaunay-fast: 117s
3. faster-delaunay: 5s
4. delaunator: 1s⚡
5. delaunator-cpp: 0.9s
6. delaunator-r...
mapbox/earcut (JS)
mapbox/earcut.hpp (C++)
пространственные индексы
github.com/mourner/rbush
github.com/mourner/kdbush
github.com/mourner/flatbush
github.com/mourner/rbush-knn
github.com/mour...
mapbox/supercluster (JS)
mapbox/supercluter-hpp (C++)
mapbox/supercluster (JS)
mapbox/supercluter-hpp (C++)
~
mapbox/geojson-vt (JS)
mapbox/geojson-vt-cpp (C++)
github.com/mapbox/webgl-wind
github.com/mapbox/potpack
mapbox/pixelmatch (JS)
mapbox/pixelmatch-cpp (C++)
математическое
образование? %
В такой чудесный, светлый день
Мне хочется писать стихами...
Но, право, ведь порою лень
Вы не желали обуздать и сами?
Конт...
Владимир Агафонкин
Идиотское введение в алгоритмы 🤪
зачем понимать
алгоритмы?
99% проблем
с быстродействием —
алгоритмического характера
приложение
фреймворки
медленный код:
код, выполняющий
лишнюю работу
алгоритмическое
мышление:
искусство отлынивать
от лишней работы (в коде)
rollup/rollup#2062
rollup: map = magicString.generateMap()
rollup: obj = decode(map)
";;;;EAEEA,EAAE,EAAC,CAAE;ECQY,UACC…"
rollup/rollup#2062
rollup: map = magicString.generateMap()
magic-string: ...
map = encode(obj)
rollup: obj = decode(map)
rollup/rollup#2062
rollup: map = magicString.generateDecodedMap()
magic-string: map = encode(obj)
rollup: obj = decode(map...
1. найти узкие места
оптимизация:
требует алгоритмического мышления
1. найти узкие места
2. выяснить, почему они медленные
3. оптимизировать
оптимизация:
O(1)
O(log n)
O(n)
O(n log n)
O(n2)
O(n3)
алгоритмическая сложность:
(= понять, почему тормозит
и что с этим делать)
способ описать,
как быстродействие меняется
с р...
1. O(1) — 1
2. O(n) — 1000
3. O(n2) — 1,000,000
4. O(n3) — 1,000,000,000
(n = 1000)
array[0] + array[1];
O(1) — моментально
O(n) — подозрительно
for (const item of array) {
sum += item;
}
O(n2) — тормозное говно
for (let i = 0, n = array.length; i < n; i++) {
for (let j = i + 1; j < n; j++) {
sum += array[i] ...
function foo(array) {
for (const item of array) {
array[array.indexOf(item)] = item + 10;
}
}
O(n2) — тормозное говно
function foo(array) {
for (const item of array) {
bar(array, item);
}
}
function bar(array, item) {
array[array.indexOf(it...
accidentallyquadratic.tumblr.com
O(n3) — невыносимо, выкинуть нафиг
for (let i = 0, n = array.length; i < n; i++) {
for (let j = i + 1; j < n; j++) {
for (...
1. O(1) — моментально
2. O(n) — подозрительно
3. O(n2) — тормозное говно
4. O(n3) — выкинуть нафиг
чорти б мене побрали!!!
хай йому грець!!
дідько!
if (j < 0) {
if (triangles.length === 0) triangles.push([i]);
return;
}
f...
array.indexOf
array.lastIndexOf
array.splice
array.includes
array.reverse
array.every
Object.values
array.find
array.some
a...
array.slice
array.concat
array.map
array.filter
str.split
подозрительные аллокации
a.slice().concat(b).map(foo)
.filter(bar).reduce(bla, 0);
выделить память и
сразу выкинуть (4 раза)
for (const b of items) {
a.slice().concat(b).map(foo)
.filter(bar).reduce(bla, 0);
}
выделить память и
сразу выкинуть (4 ра...
имьютабилити!
реактивность!
функциональное
программирование!
чертовы
аллокации
function foo() {
…
return [x, y];
}
const [x, y] = foo();
JIT-оптимизатор в
JS-движках не всегда
понимает, чего вы хотите
пишите код максимально
предсказуемо, чтобы движок
поменьше угадывал
Rich-Harris/sourcemap-codec#71
const lines = input.split(';');
for (const line of lines) {
const segments = line.split(','...
Rich-Harris/sourcemap-codec#71
for (let i = 0; i < input.length; i++) {
const c = input.charCodeAt(i);
if (c === 44) { // ...
O(1) O(n)O(log n)
O(log n) — очень быстро
1 1,000,00020
O(log n) — очень быстро
бинарный поиск 🔍
o(log n)
rollup/rollup#2228
…
в 40 раз быстрее
1. O(n) → O(log n)
2. O(n log n) → O(n)
3. O(n2) → O(n log n)
4. O(n3) — выкинуть
алгоритмическая оптимизация:
медленно медленно медленно
алгоритмическая оптимизация:
организовать данные
алгоритмическая оптимизация:
алгоритмическая оптимизация:
сделать больше в начале, 

чтобы делать меньше 

каждый следующий раз
структуры данных:
как организорвать данные
для быстрого поиска и
обновления
• hash map
• hash set
• binary search tree
• priority heap
• linked list
• interval tree
• grid
• r-tree
• quadtree
• kd-t...
отсортированный массив
o(n log n)
❤ любимая структура данных:
отсортировать вокруг элемента,
чтобы все слева были меньше
o(n)
github.com/mourner/quickselect
39, 28, 28, 33, 21, 12, 22,...
github.com/mourner/kdbush
priority queue:
push: o(1)
top: o(1)
pop: o(log n)
github.com/mourner/tinyqueue
github.com/mourner/flatqueue
{
'1': 10,
'2': 20,
'3': 30
};
{
'0': 10,
'1': 20,
‘2': 30
};
HashTable Array
[10, 20, 30];
istanbuljs/istanbul-lib-instrument#22
{
'1': 10,
'2': 20,
'3': 30
};
{
'0': 10,
'1': 20,
‘2': 30
};
в 15 раз быстрее 😱
все необходимое уже
изобрели до вас*
*но реализовали через ж🤬
как я читаю

научные публикации 

и прилагаемый код
1. думайте, как оно работает 🤔

2. не бойтесь лезть в чужой код +

3. не бойтесь изобретать велосипеды 🚴

4. участвуйте в ...
спасибо
agafonkin.com
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышление на практике для JS-разработчиков
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышление на практике для JS-разработчиков
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышление на практике для JS-разработчиков
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышление на практике для JS-разработчиков
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышление на практике для JS-разработчиков
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышление на практике для JS-разработчиков
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышление на практике для JS-разработчиков
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышление на практике для JS-разработчиков
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышление на практике для JS-разработчиков
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышление на практике для JS-разработчиков
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышление на практике для JS-разработчиков
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышление на практике для JS-разработчиков
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышление на практике для JS-разработчиков
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышление на практике для JS-разработчиков
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышление на практике для JS-разработчиков
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышление на практике для JS-разработчиков
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышление на практике для JS-разработчиков
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышление на практике для JS-разработчиков
Upcoming SlideShare
Loading in …5
×

JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышление на практике для JS-разработчиков

67 views

Published on

Мы так сильно полагаемся на фреймворки, что уже забыли, как работают компьютеры. Когда что-то сильно тормозит и непонятно, как это решить, приходится учиться мыслить алгоритмически. Как анализировать "узкие" места в коде? Выполняет ли код лишнюю работу? Как можно достичь того же результата, делая меньше? Практикуя алгоритмическое мышление, отвечать на подобные вопросы становится гораздо легче, и рано или поздно вы научитесь писать код так, чтобы он был быстрым изначально, по умолчанию. Так что позвольте мне познакомить вас с алгоритмами еще раз, в практичном виде, применимом в вашей повседневной работе.

Published in: Education
  • Be the first to comment

  • Be the first to like this

JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышление на практике для JS-разработчиков

  1. 1. Владимир Агафонкин ⚡Быстро по умолчанию: алгоритмическое мышление на практике
  2. 2. rain.in.ua
  3. 3. одержимый скоростью кода
  4. 4. ❤❤❤ open source
  5. 5. 1. 🌱 Найти узкую задачу 2. ⚡ Создать для нее самую быструю и простую в мире JavaScript-библиотеку 3. 🔄 Перейти к пункту №1
  6. 6. 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
  7. 7. github.com/mapbox/delaunator
  8. 8. github.com/d3/d3-delaunay
  9. 9. 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
  10. 10. mapbox/earcut (JS) mapbox/earcut.hpp (C++)
  11. 11. пространственные индексы
  12. 12. 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
  13. 13. mapbox/supercluster (JS) mapbox/supercluter-hpp (C++)
  14. 14. mapbox/supercluster (JS) mapbox/supercluter-hpp (C++)
  15. 15. ~ mapbox/geojson-vt (JS) mapbox/geojson-vt-cpp (C++)
  16. 16. github.com/mapbox/webgl-wind
  17. 17. github.com/mapbox/potpack
  18. 18. mapbox/pixelmatch (JS) mapbox/pixelmatch-cpp (C++)
  19. 19. математическое образование? %
  20. 20. В такой чудесный, светлый день Мне хочется писать стихами... Но, право, ведь порою лень Вы не желали обуздать и сами? Контрольная, смотрю, весьма сложна, И отвечать совсем уж неохота, Когда за окнами прекрасная весна, И о ассемблере не мыслиться чего-то...
  21. 21. Владимир Агафонкин Идиотское введение в алгоритмы 🤪
  22. 22. зачем понимать алгоритмы?
  23. 23. 99% проблем с быстродействием — алгоритмического характера
  24. 24. приложение фреймворки
  25. 25. медленный код: код, выполняющий лишнюю работу
  26. 26. алгоритмическое мышление: искусство отлынивать от лишней работы (в коде)
  27. 27. rollup/rollup#2062 rollup: map = magicString.generateMap() rollup: obj = decode(map) ";;;;EAEEA,EAAE,EAAC,CAAE;ECQY,UACC…"
  28. 28. rollup/rollup#2062 rollup: map = magicString.generateMap() magic-string: ... map = encode(obj) rollup: obj = decode(map)
  29. 29. rollup/rollup#2062 rollup: map = magicString.generateDecodedMap() magic-string: map = encode(obj) rollup: obj = decode(map) source map’ы на 40% быстрее
  30. 30. 1. найти узкие места оптимизация:
  31. 31. требует алгоритмического мышления 1. найти узкие места 2. выяснить, почему они медленные 3. оптимизировать оптимизация:
  32. 32. O(1) O(log n) O(n) O(n log n) O(n2) O(n3)
  33. 33. алгоритмическая сложность: (= понять, почему тормозит и что с этим делать) способ описать, как быстродействие меняется с размером данных
  34. 34. 1. O(1) — 1 2. O(n) — 1000 3. O(n2) — 1,000,000 4. O(n3) — 1,000,000,000 (n = 1000)
  35. 35. array[0] + array[1]; O(1) — моментально
  36. 36. O(n) — подозрительно for (const item of array) { sum += item; }
  37. 37. 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]; } }
  38. 38. function foo(array) { for (const item of array) { array[array.indexOf(item)] = item + 10; } } O(n2) — тормозное говно
  39. 39. function foo(array) { for (const item of array) { bar(array, item); } } function bar(array, item) { array[array.indexOf(item)] = item + 10; } O(n2) — тормозное говно
  40. 40. accidentallyquadratic.tumblr.com
  41. 41. 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]; } } }
  42. 42. 1. O(1) — моментально 2. O(n) — подозрительно 3. O(n2) — тормозное говно 4. O(n3) — выкинуть нафиг
  43. 43. чорти б мене побрали!!! хай йому грець!! дідько! 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
  44. 44. 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) — подозрительно
  45. 45. array.slice array.concat array.map array.filter str.split подозрительные аллокации
  46. 46. a.slice().concat(b).map(foo) .filter(bar).reduce(bla, 0); выделить память и сразу выкинуть (4 раза)
  47. 47. for (const b of items) { a.slice().concat(b).map(foo) .filter(bar).reduce(bla, 0); } выделить память и сразу выкинуть (4 раза)
  48. 48. имьютабилити! реактивность! функциональное программирование! чертовы аллокации
  49. 49. function foo() { … return [x, y]; } const [x, y] = foo();
  50. 50. JIT-оптимизатор в JS-движках не всегда понимает, чего вы хотите
  51. 51. пишите код максимально предсказуемо, чтобы движок поменьше угадывал
  52. 52. 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) { ... } } }
  53. 53. 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) { // ";" ... в три раза быстрее
  54. 54. O(1) O(n)O(log n) O(log n) — очень быстро
  55. 55. 1 1,000,00020 O(log n) — очень быстро
  56. 56. бинарный поиск 🔍 o(log n)
  57. 57. rollup/rollup#2228 … в 40 раз быстрее
  58. 58. 1. O(n) → O(log n) 2. O(n log n) → O(n) 3. O(n2) → O(n log n) 4. O(n3) — выкинуть алгоритмическая оптимизация:
  59. 59. медленно медленно медленно алгоритмическая оптимизация:
  60. 60. организовать данные алгоритмическая оптимизация:
  61. 61. алгоритмическая оптимизация: сделать больше в начале, чтобы делать меньше каждый следующий раз
  62. 62. структуры данных: как организорвать данные для быстрого поиска и обновления
  63. 63. • hash map • hash set • binary search tree • priority heap • linked list • interval tree • grid • r-tree • quadtree • kd-tree структуры данных:
  64. 64. отсортированный массив o(n log n) ❤ любимая структура данных:
  65. 65. отсортировать вокруг элемента, чтобы все слева были меньше o(n) github.com/mourner/quickselect 39, 28, 28, 33, 21, 12, 22, 50, 53, 56, 59, 65, 90, 77, 95
  66. 66. github.com/mourner/kdbush
  67. 67. priority queue: push: o(1) top: o(1) pop: o(log n) github.com/mourner/tinyqueue github.com/mourner/flatqueue
  68. 68. { '1': 10, '2': 20, '3': 30 }; { '0': 10, '1': 20, ‘2': 30 }; HashTable Array [10, 20, 30];
  69. 69. istanbuljs/istanbul-lib-instrument#22 { '1': 10, '2': 20, '3': 30 }; { '0': 10, '1': 20, ‘2': 30 }; в 15 раз быстрее 😱
  70. 70. все необходимое уже изобрели до вас* *но реализовали через ж🤬
  71. 71. как я читаю научные публикации и прилагаемый код
  72. 72. 1. думайте, как оно работает 🤔 2. не бойтесь лезть в чужой код + 3. не бойтесь изобретать велосипеды 🚴 4. участвуйте в open source ❤ 5. постоянно упрощайте 🌱 6. практикуйте оптимизацию 🔄, и вы научитесь писать код, который сразу работает быстро
  73. 73. спасибо agafonkin.com

×