JavaScript превратился в более читаемый язык. В этом нет никаких сомнений, и в этом нет никакого вреда.
Разработка программного обеспечения - это динамичный рынок, где команды постоянно меняются, а это означает, что код должен быть читаемым для новичков. Но разве это в ущерб производительности?
Где провести грань между производительностью и удобочитаемостью? Когда мы жертвуем тем или другим? Нужно ли когда-нибудь жертвовать одним из них?
Это некоторые из вопросов, на которые я хотел бы ответить или, по крайней мере, попытаться понять вместе.
Причины попыток достичь высокого уровня производительности в вашем коде должны быть очевидны, но почему мы так одержимы удобочитаемостью?
Та же проблема, разные решения
Что ж, некоторое время назад было очень распространено увидеть что-то в этом роде для следующей проблемы:
Учитывая массив неупорядоченных чисел, верните новый массив, добавив 1 к каждому значению и отсортировав его, не изменяя исходный
var numbers = [2, 4, 12, 6, 8, 29, 5, 10, 87, 11, 7]; function process(arr) { let newArr = arr.slice(); newArr[0]++; for (let i = 1; i < newArr.length; i++) { const current = newArr[i] + 1; let leftIndex = i - 1; while (leftIndex >= 0 && newArr[leftIndex] > current) { newArr[leftIndex + 1] = newArr[leftIndex]; leftIndex = leftIndex - 1; } newArr[leftIndex + 1] = current; } return newArr; } const newArray = process(numbers);
(Я использую сортировку вставкой, потому что ее проще реализовать)
Этот образец кода на самом деле не читается, но все же он производительный, намного более производительный, чем читаемый код ES6, например, этот:
const process = (arr) => arr .map(num => num + 1) .sort((a, b) => a - b); const newArray = process(numbers);
Фактически, первый пример кода примерно на 75% быстрее, чем второй, хотя второй пример более читабелен и даже может быть упрощен до однострочника:
const newArray = numbers.map(num => num + 1).sort((a, b) => a - b);
Или разделите вспомогательными функциями для лучшей читаемости:
const addOne = (n) => n + 1; const asc = (a, b) => a - b; const newArray = numbers.map(addOne).sort(asc);
Очевидно, что образец ES6 (при любом подходе) более читабелен, что упрощает понимание кода с первого взгляда. С помощью читаемого кода мы можем быстрее знакомить новых разработчиков с проектами, мы можем легче делиться нашим кодом, и он становится более удобным в обслуживании.
Учитывая все обстоятельства, в большинстве случаев производительность становится необязательной. Вот почему ES6 так эволюционировал.
Окончательное сравнение обоих подходов:
На этом этапе вы, вероятно, спросите себя: «Что еще менее эффективно, но более читабельно?»
Что ж, давайте вместе рассмотрим некоторые из основных сценариев использования.
Синтаксис распространения против Object.assign ()
Возьмем следующую простую задачу:
Скопируйте объект и добавьте к копии новое свойство
Решения:
const params = {...}; // filled Object // ES6 - Spread syntax var copy1 = { a: 2, ...params }; // Object.assign() var copy2 = Object.assign({}, { a: 2 }, params);
Оба этих подхода делают свою работу, но мы все можем согласиться с тем, что синтаксис распространения более читабелен, хотя он на ~ 54% медленнее.
Для цикла против уменьшения
Проблема:
Суммируйте все значения массива
Решения. Начнем с классического цикла for…:
const numbers = [2, 4, 12, 6, 8, 29, 5, 10, 87, 11, 7]; function arraySum(arr) { let sum = 0; for (let i = 0; i < arr.length; i++) { sum += arr[i] } return sum; } const sumOfNumbers = arraySum(numbers);
А теперь приступим к самому могущественному reduce:
const numbers = [2, 4, 12, 6, 8, 29, 5, 10, 87, 11, 7]; const add = (a, b) => a + b; const arraySum = (arr) => arr.reduce(add); const sumOfNumbers = arraySum(numbers);
В этом случае reduce чрезвычайно дорого с точки зрения производительности, на ~ 96% медленнее!
Для vs while vs do while
Разница почти незаметна, но, тем не менее, в случае сомнений… Воспользуйтесь классическим циклом for.
Когда что использовать?
Ух ты! Теперь это хит ... Я использую синтаксис распространения, сокращение и т. Д. Для всех своих операций!
Настроение тут вроде бы удручающее, нам обещали читабельность без затрат на производительность! Я хочу свои деньги обратно! (режим паники)
Не будем паниковать и проанализируем ситуацию. Итак, «Когда что использовать?»
Ответить на поставленный выше вопрос проще, чем ожидалось: Зависит.
Возвращаясь к первому примеру, если нам нужно: скопировать, добавить и отсортировать массив или объект малого или среднего размера… Затем мы перейдем к удобочитаемости, мы будем использовать все доступные игрушки в арсенале ES6.
Фактически, почти весь наш код может быть написан с упором на удобочитаемость, а не на производительность, конечно, в зависимости от проекта.
Попробуем внести это в списки.
Когда отдавать предпочтение удобочитаемости
- Когда данные, с которыми мы имеем дело, не очень большие
- Когда приложение работает правильно с точки зрения скорости, нагрузки и т. Д.
- При работе в динамичной среде с большим количеством новичков в проекте.
- При написании библиотеки или плагина, которые людям, возможно, придется прочитать и понять
Когда отдавать предпочтение производительности
- При работе с большими данными
- Когда приложение работает медленно или возникают другие проблемы с производительностью
- Когда проект должен быть масштабируемым
- При работе в личном проекте пишите как хотите
Итак, если мы имеем дело с большими данными, избегайте использования синтаксиса сокращения, фильтрации, сопоставления, распространения и т. Д. В той части кода, которая конкретно имеет дело с этим объектом или массивом.
Выводы
Вместо того, чтобы окунуться в новейшие и самые крутые вещи, мы все должны сделать шаг назад и проанализировать, удобно ли это для нашего проекта и нашего варианта использования.
Несомненно, новые функции ES6 являются благословением и делают ежедневное кодирование с помощью JavaScript удовольствием, но если мы боремся с производительностью, если мы обрабатываем большие объемы данных ... Мы должны пересмотреть, какие инструменты мы используем.
Для тяжелой работы я использую менее читаемый код, но более производительный. 💪
Для больших объемов данных я исследую и внедряю наиболее эффективные алгоритмы для решения этой задачи. 💪 👓
В остальном я предпочитаю читаемую красоту ES6! ❤
Отказ от ответственности
Результаты тестирования, представленные в этом сообщении, могут незначительно отличаться в зависимости от рабочей нагрузки браузера, ОС и сервера.
📝 Прочтите этот рассказ позже в Журнале.
🗞 Просыпайтесь каждое воскресное утро и слышите самые интересные истории, мнения и новости недели, ожидающие в вашем почтовом ящике: Получите примечательный информационный бюллетень›