Software Engineer
  • «Найсильнішу контузію я отримав від вибуху авіаційної бомби на пів тонни». Айтівець — про рік перебування на «нулі» та повернення до цивільного життя

    Радий тебе чути! Дякую за службу!

  • Співбесіда з JavaScript. 300+ запитань для Junior, Middle, Senior

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

    — Сколько извесных людей из мира JS знаете лично

    и сеньору:

    — Сколько извесных людей из мира JS занют вас лично
  • Опановуємо основи алгоритмів, або Як прискорити код з 15 до 1000 запитів за секунду

    основною структурою буде завжди хеш таблиця (не має значення чи то об’єкт чи його похідна — массив).

    .
    — ні. у випадку об’єкта — це буде хеш таблиця. у випадку Array — буде List. ryanpeden.com/...​rays-work-under-the-hood.

    Да верно, забыл об этом:
    PACKED_SMI_ELEMENTS — a packed integer array
    PACKED_DOUBLE_ELEMENTS — a packed double array
    PACKED_ELEMENTS — a packed object array
    HOLEY_SMI_ELEMENTS — a sparse integer array
    HOLEY_DOUBLE_ELEMENTS — a sparse double array
    HOLEY_ELEMENTS — a sparse object array
    DICTIONARY_ELEMENTS — a very sparse array that is backed by a dictionary

    И собственно еще одно правил:
    4) По возможности, данные в JS массиве должы быть однородны

    Підтримав: Іван Бранець
  • Опановуємо основи алгоритмів, або Як прискорити код з 15 до 1000 запитів за секунду

    const start = new Date();
    const obj = JSON.parse(jsonStr);
    console.log(`${new Date().getTime() - start.getTime()}ms`, jsonStr.length);

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

    Відповідь приходить за 300 мілісекунд

    Очень хорошо, но это по прежнему самая медленная часть, ускорение которой и должна привести к основному росту производительности.

    Вы не внимательно прочитали мой ответ и повторяете мои слова как утверждение мне же:

    файла приблизно 3.3мб у запакованому вигляді приблизно 200кб
    Тоді додав CDN, він цей файлик зжимає через gzip і маємо 200кб.

    Насчет моих расчетов:

    (800 + 100 + 2) * 1000 / (1000 * 60) ≈ 15 хвилин.
    Це все в разрахунку для синхронного коду.

    Это предположение было заведомо упрощением, и я как раз про это и пишу. Т.к. исходные характеристики сервера который будет отдавать мне эти данные не известны, я могу лишь описать худший вариан.

    З цифр випливае наступна оптимізація по порядку:
    1) Тримати відкрите підключення, чи пул підключень до сервера
    2) Змінити формат данних, щоб уникнути парсинга великого за об’ємом JSON (наприклад стрімити чанки JSON/CSV)
    3) Оптимизувати алгоритм, якщо це стало bottleneck
    4) Замінити Nodejs на більш «продуктивний» сервер чи змінити подхід до агрегації данних (наприклад використовувати спеціалізовані БД)
    Цікавий висновок. Спочатку показати, що в нас 800 — це найбільший таймаут (сторонній API + мережа), а потім сказати, «4) Замінити Nodejs на більш „продуктивний“ сервер».

    Я привел нумерованый список оптимизации в порядке убывание важности их решения. Когда дело дойдет до момента когда Nodejs не будет справляться с задачей, то да, лучше ее заменить.

    Нода виконує операції Event Loop в одному потоці. Але це не означає, що I/O операції також повинні виконуватися в одному потоці. Нода використовує багатопоточність, але вона схована від розробника.

    Все же мне кажется, что основное преимущество Nodejs — это асинхронность, а не многопоточнось.

    Можете мне ответить на одни вопрос. Нужно ли столько «оптимизировать» если изначально оталкиваться в написании кода на Nodejs от неких парадигм, например:
    1.

    основною структурою буде завжди хеш таблиця (не має значення чи то об’єкт чи його похідна — массив).

    2. Не блокируй EventLoop.
    2.

    Ипользовании сторонней библиотеки, где нативная конструкция занимает столько же места это антипатерн.

    3. Избегать вложенных циклов, где это возможо (Плоское лучше, чем вложенное — The Zen of Python, by Tim Peters).

    И да, я не говорю, что не нужно знать базовые алгоритмы и структуры данных.

  • Опановуємо основи алгоритмів, або Як прискорити код з 15 до 1000 запитів за секунду

    Добре, припустимо, що задача побудувати сервис, який би отимував данні зі сторонього ресурсу для 1000 міст раз на годину та робив по ним агрегацію. Доречі, для работи з большою кількостью за об’ємом та трафиком данних, що требо бистро серелізувати/десерелізувати, Nodejs не дуже підійде, бо це CPU bound EventLoop блокуючий процесс.

    Якщо грубо підрахувати:
    Розмір файла приблизно 3.3мб у запакованому вигляді приблизно 200кб(цифри отримав з браузеру). Загрузка одного файлу з ресурсу якщо встановлювати з’єднання то > 800 мс у Firefox. Для простоти вважаемо що разпаковка файла 0 мс, далі йде парсинг JSON.parse > 100 мс (прогнав пару раз на локальной машині с данними) далі логіка 2-176 мс (сюди вже включено JSON.stringify < 1 мс)(зі статті).

    При прочих сталих в найгиршому випадку маємо: (800 + 100 + 176) * 1000 / (1000 * 60) ≈ 18 хвилин, а для найкращого: (800 + 100 + 2) * 1000 / (1000 * 60) ≈ 15 хвилин.
    Це все в разрахунку для синхронного коду.

    З цифр випливае наступна оптимізація по порядку:
    1) Тримати відкрите підключення, чи пул підключень до сервера
    2) Змінити формат данних, щоб уникнути парсинга великого за об’ємом JSON (наприклад стрімити чанки JSON/CSV)
    3) Оптимизувати алгоритм, якщо це стало bottleneck
    4) Замінити Nodejs на більш «продуктивний» сервер чи змінити подхід до агрегації данних (наприклад використовувати спеціалізовані БД)

    Но зі статті випливає, що єдиною оптимізацією є алгорітм.
    Вся «оптимізація» в таких випадках, це ефективно використання особливості JS, що основною структурою буде завжди хеш таблиця (не має значення чи то об’єкт чи його похідна — массив).

    Підтримав: Yuri Predborski
  • Performance of Performance Testing tools

    Спасибо за статью! Не планировали расширить тест фреймворки, скажем, Siege, Artillery,
    Hey
    , Yandex Tank? Или может написать обзор по зоопарку инструментов тестирования и когда какой лучше применять?

    Підтримав: Oleksii Ostapov
  • Опановуємо основи алгоритмів, або Як прискорити код з 15 до 1000 запитів за секунду

    Дуже суб’єктивні твердження. Дайте об’єктивні метрики, щоб можна було почати діалог.

    Тобто ви вважаєте, що такий спосіб ітерації по масиву це нормально?

    while (source.length > 0) { source.splice(0, 1); }

    Ваша перша оптимізація заключалася в виклученні бібліотекі та заміну її на нативний код, чому вас дивує ствердження:

    Ипользовании сторонней библиотеки, где нативная конструкция занимает столько же места это антипатерн.

    Далі ви використовуєте lodash для простих операцій, котрі теж можно замінити на нативний код.

    В последнем примере у вас лишняя операция (создание массива с ключами
    Затегайте код, напишіть, як має виглядати за вашою версією, покажіть різницю продуктивності.
    const dates = Object.keys(groupedByDate);
    const meanTemperaturesByDate: { date: string, meanTemperature: number }[] =
    dates.map(date => {
    const temperaturesInOneDay = groupedByDate[date];
    return {
    date,
    meanTemperature: _.meanBy(temperaturesInOneDay, item => item.temperature)
    }
    })

    Можно замінити на:

    const meanTemperaturesByDate = [];
    for (const date in groupedByDate) {

    const meanTemperature = groupedByDate[date].reduce((a,b) => a + b) / groupedByDate[date].length

    meanTemperaturesByDate.push({ date, meanTemperature })
    }

    Але все це не оптимізація, а написання логічного кода з використанням структур данних та інструментів які є в цій мові програмування.

    Ви намалювали «сферичного коня в вакуумі» для сладной сістемі спростивши її у зручний вам спосіб, тому всі ці запитання й з’явилися. Чому ви вичитуєте у пам’ять вихідний JSON, хоча серелізація цього об’єкту є самою затратною операцією і JSON.parse блокує Event Loop? Чому на останьому етапі підіймаєте ще один сервіс, коли даже с першим варіантом кода та кешем можно було б збільшити показники відповіді в рази по відношенню з останнім кодом? Чому ви взяли js код як приклад оптимізації, коли вся оптимізація трапляеться в ньому under the hood і метрики продуктивності дуже залежать від системи та способа вимірювання?

    Підтримав: Yuri Predborski
  • Опановуємо основи алгоритмів, або Як прискорити код з 15 до 1000 запитів за секунду

    А можно лінк де написано, що масив у JS це не об’єкт.

  • Опановуємо основи алгоритмів, або Як прискорити код з 15 до 1000 запитів за секунду

    • У вас все примеры до пятого не прошли бы code review, а написать такое можно только будучи низкоквалифицированным специалистом и/или большой спешке и потом не читать. Поэтому, это скорее обучение как нужно писать код в целом, а не про оптимизацию алгоритма.
    • Ипользовании сторонней библиотеки, где нативная конструкция занимает столько же места это антипатерн. В последнем примере у вас лишняя операция (создание массива с ключами) — по ключам объекта можно итерировать и пушить в массив уже агрегированные данные.
    • Зачем нужна оптимизация если основная задача веб-сервера — IO, в реальных системах, первый шаг при создании/оптимизации будет выделение CPU bound операций в отдельный сервис, иначе, получается выполнение различного рода задач в рамках одного процесса и этот процесс будет заведомо хуже масштабируем.
    • Выбор данных очень неудачный, мало того что небольшой по объему, так еще и обновляется раз в час. Это уже ETL процесс, можно написать скрипт на любом языке и в статике хранить результат.
    • Как связаны деревья поиска с данной задачей?
    • Горизонтальное масштабирование сервера == оптимизация CPU bound алгоритма?