Почему не стоит заморачиваться с написанием оптимизированного кода

Год назад девочка перевела статью про подходы к оптимизации javascript кода. Про мелочные по сути вещи (использование arguments, switch-case, try-catch, for-in). Запустила тесты сегодня, через год, увидела что проседания производительности по этим пунктам нет. Статья на Хабре https://habrahabr.ru/post/319936/

Мои пять копеек к этому вопросу. Если бы ты написал оптимизированный за счет циклов, или отказался от for-in по причине “оптимизации”, то имел бы сегодня код, который не имеет эффекта оптимизации, но наделен деформациями, необходимыми. Эти деформации могут усложнять понимание кода, особенно для новичков.

Хочешь писать код качественно - пиши его в первую очередь для людей. Оптимизируй для понимания человека (меньше связей, меньше ветвлений, проще функции). Избегай однозначно медленной работы с DOM-мом, но ни в коем случае не в ущерб читаемости.

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

Сталкиваясь с проблемой производительности, даже не задумывайся оптимизировать работу с массивами (например замена forEach на цикл for) до того как будешь уверен что все попытки оптимизировать DOM приняты. На мой взгляд оптимизация скорости работы с массивами и switch-case, try-catch - экономия на спичках.

Всегда используй цифры (console.time, console.timeEnd а так же flamechart в средствах разработчика хрома) чтобы ориентироваться на сколько в абсолютных значениях твое изменение повлияло на производительность, не оптимизируй код “вслепую”. Не раз имел опыт когда “слепая” оптимизация только усугубляла ситуацию, а автор не мог этого опознать только потому что не пользовался замерами.

3 лайка

Для тех, кто любит JS со вкусом функциональности, это вообще может быть больной темой. Есть знакомые олдфаги, которые на дух не переносят«функциональный тренд» и не против построить в аду особую печь для тех, кто пишет в функциональном стиле (стало быть и для меня :]). На том же хабре был забавный пример разницы в производительности для разных подходов, так вот же он:

const keys = []; for(let i = 0; i < 100000; i += 10) keys.push(i); 

console.time('mutable');
const obj1 = {};
for(let key of keys) obj1[key] = key;
console.timeEnd('mutable');

console.time('reduce');
const obj2 = keys.reduce((o, key) => Object.assign({}, o, { [key]: key }), {});
console.timeEnd('reduce');

Щас запустил в хроме, результаты:

mutable: 5.450ms
reduce: 21257.278ms

keys.reduce((o, key) => Object.assign({}, o, { [key]: key }), {});

Добиваться иммутабельности там, где она не задумана, неоптимальным способом (каждый раз заново копируя в новый объект все свойства из предыдущего)? Так себе пример для довода о производительности. Чуваку бы стоило научиться разговаривать на javascript, а не пытаться говорить на хаскеле джаваскриптовыми методами.

Я бы выбрал путь иметь все метательные операции в рамках одной reduce функции: и понятно что в результате получается единое значение из всего массива, и все мутации собраны в одном месте, так что не придется растекаться мыслью по коду:

const keys = []; for(let i = 0; i < 100000; i += 10) keys.push(i); 

console.time('reduce');
const obj2 = keys.reduce((o, key) => {
	o[key] = key
	return o
}, {});
console.timeEnd('reduce'); // reduce: 6.535ms

Я с тобой согласен и пример тоже хороший. Просто продемонстрированный код чувака показывает что бывает, когда бескомпромиссно ударяешься в иммутабельность, под которую JS не заточен, и что получается на выходе (цена религии иммутабельности в этом конкретном случае будет стоить ~ 4000 раз понижением производительности). Об этом нужно быть осведомленным.

1 лайк