Обычно я ненавижу слово «преждевременная оптимизация», но это пахнет им. Стоит отметить, что Кнут использовал эту знаменитую цитату в контексте использования goto
операторов для ускорения работы кода в критических областях. Это ключ: критические пути.
Он предлагал использовать goto
для ускорения кода, но предостерегал против тех программистов, которые хотели бы делать такие вещи, основываясь на догадках и суевериях для кода, который даже не критичен.
Одностороннее предпочтение switch
выражений как можно более равномерно по всей базе кода (независимо от того, обрабатывается ли большая нагрузка) - классический пример того, что Кнут называет «программистом и безумным» программистом, который целый день изо всех сил старается сохранить их «оптимизированными». "код, который превратился в отладочный кошмар в результате попытки сэкономить копейки за фунты. Такой код редко обслуживаем, не говоря уже о том, что он эффективен.
Он прав?
Он прав с точки зрения эффективности. Ни один компилятор, насколько мне известно, не может оптимизировать полиморфный код, включающий объекты и динамическую диспетчеризацию, лучше, чем оператор switch. Вы никогда не получите LUT или таблицу перехода к встроенному коду из полиморфного кода, поскольку такой код имеет тенденцию служить барьером оптимизатора для компилятора (он не будет знать, какую функцию вызывать до момента, когда происходит динамическая диспетчеризация). происходит).
Более полезно не думать об этой стоимости с точки зрения таблиц переходов, а с точки зрения барьера оптимизации. Для полиморфизма вызов Base.method()
не позволяет компилятору знать, какая функция в действительности будет вызвана, если method
она виртуальная, не запечатана и может быть переопределена. Поскольку он не знает, какая функция на самом деле будет вызываться заранее, он не может оптимизировать вызов функции и использовать больше информации при принятии решений по оптимизации, поскольку на самом деле он не знает, какая функция будет вызываться при время компиляции кода.
Оптимизаторы работают лучше всего, когда они могут вглядываться в вызов функции и делать оптимизации, которые либо полностью выравнивают вызывающего и вызываемого абонентов, либо, по крайней мере, оптимизируют вызывающего абонента для наиболее эффективной работы с вызываемым абонентом. Они не могут этого сделать, если не знают, какая функция будет вызываться заранее.
Он просто говорит свою задницу?
Использование этой стоимости, которая часто составляет копейки, чтобы оправдать превращение ее в стандарт кодирования, применяемый единообразно, как правило, очень глупо, особенно для мест, где есть потребность в расширяемости. Это главное, на что вы должны обращать внимание с настоящими преждевременными оптимизаторами: они хотят превратить незначительные проблемы с производительностью в стандарты кодирования, применяемые единообразно во всей кодовой базе, не обращая внимания на удобство сопровождения.
Я немного обижаюсь на цитату «старого хакера», использованную в принятом ответе, поскольку я один из них. Не каждый, кто десятилетиями занимался кодированием, начиная с очень ограниченного аппаратного обеспечения, превратился в преждевременного оптимизатора. Тем не менее, я столкнулся и работал с ними тоже. Но эти типы никогда не измеряют такие вещи, как неправильное предсказание ветвлений или ошибки кэширования, они думают, что знают лучше, и основывают свои представления о неэффективности на сложной производственной кодовой базе, основанной на суевериях, которые сегодня не верны, а иногда и никогда не сбываются. Люди, которые по-настоящему работали в областях, критичных к производительности, часто понимают, что эффективная оптимизация - это эффективная расстановка приоритетов, а попытка обобщить стандарт кодирования, ухудшающий ремонтопригодность, для экономии копеек - очень неэффективная расстановка приоритетов.
Копейки важны, когда у вас есть дешевая функция, которая не выполняет так много работы, которая вызывается миллиард раз в очень узкой, критичной для производительности петле. В этом случае мы сэкономим 10 миллионов долларов. Брать копейки не стоит, если у вас есть функция, вызываемая дважды, для которой одно тело стоит тысячи долларов. Не стоит тратить время на то, чтобы тратить время на копейки во время покупки автомобиля. Стоит поторговаться за копейки, если вы покупаете миллион банок содовой у производителя. Ключом к эффективной оптимизации является понимание этих затрат в их правильном контексте. Кто-то, кто пытается сэкономить копейки на каждой покупке и предлагает, чтобы все остальные пытались торговать копейки независимо от того, что они покупают, не является опытным оптимизатором.