Після минулого поста хочу від себе розписати три неочевидні місця, де нода тихо гальмує майже у всіх
Більшість порад про те, чому JS повільний, написані років вісім тому і давно неправда. І аішка їх просто перекаже, бо вчилась на них же
1. await не рятує від зависання
Є важкий цикл. Розбиваєш його на 60 тисяч дрібних шматків і між ними ставиш await, щоб бот встигав слухати біржу. Логічно ж
Поставив поруч вебсокет і порахував, скільки повідомлень пройде:
через await - 0
через process.nextTick - 0
через setImmediate - 30 000
await тільки виглядає як пауза. Поки крутиться цикл, фід мертвий: ні цін, ні ордерів, ні хартбіта. А в моніторингу краса, CPU 100%, всі задоволені)
Реально пропускає тільки setImmediate
2. Один символ = 345 мегабайт
Вирізаєш з рядка шматок від 13 символів, а V8 його не копіює. Він лишає посилання на весь оригінал, і оригінал висить у пам'яті, поки живий шматок
Взяв 200 повідомлень по мегабайту, вирізав з кожного шматочок, оригінали викинув:
шматок 12 символів - 2 МБ
шматок 13 символів - 345 МБ
Різниця в один символ. Хуй ти таке на код-рев'ю побачиш))
На практиці: витяг з фрейма тікер, поклав у стакан, і тягнеш за ним весь фрейм. Пам'ять пухне, потім GC зупиняє все на кілька мілісекунд. Звісно ж у найгірший момент
Лікується так: Buffer.from(s).toString()
3. ws сам вмикає стиснення
Бібліотека ws на клієнті за замовчуванням просить біржу стискати трафік. Ти цього не писав, ти написав new WebSocket(url)
І якщо біржа погоджується, кожне повідомлення доводиться розпаковувати окремо
20 000 повідомлень:
за замовчуванням - 11 372 в секунду
з perMessageDeflate: false - 249 059 в секунду
22 рази на рівному місці. Перевіряється одним рядком: console.log(ws.extensions)
Мораль проста. Всі обговорюють хитрі оптимізації движка, а ріжуть тебе банальності. І ламаються вони не рівномірно. Більше волатильності на ринку - більше повідомлень, більше сміття, довші паузи. Тобто бот тупить рівно в ті секунди коли реально треба забирати деньги
Post #62
1.23K
- ❤ 14
- ✍ 7
- 👍 5
- 🔥 1