Знаете ли вы, что на процессорах x86 эффективнее делать x ^= x
, где x - 32-разрядное целое число, чем x = 0
?Это правда, и, конечно, имеет тот же результат.Следовательно, каждый раз, когда можно увидеть x = 0
в коде, можно заменить его на x ^= x
и повысить эффективность.
Теперь, вы когда-нибудь видели x ^= x
в большом количестве кода?
причина, по которой вы этого не сделали, заключается не только в том, что выигрыш в эффективности незначителен, но и в том, что это именно то изменение, которое будет делать компилятор (если компилируется в нативный код) или джиттер (если компилируется IL или подобное).Разберите некоторый код x86, и нередко можно увидеть ассемблерный эквивалент x ^= x
, хотя код, скомпилированный для этого, почти наверняка имел x = 0
или, возможно, что-то намного более сложное, например x = 4 >> 6
или x = 32 - y
, где анализкод показывает, что y
всегда будет содержать 32
в этой точке и т. д.
По этой причине, хотя известно, что x ^= x
более эффективен, подошва Эффект этого в подавляющем, подавляющем большинстве случаев будет делать код менее читабельным (единственное исключение будет в том случае, когда выполнение x ^= y
влечет за собой использование алгоритма, и мы оказались в случае, когда x
и y
здесь были одинаковыми, в этом случае x ^= x
сделает использование этого алгоритма более понятным, в то время как x = 0
скроет его).
В 99,999999% случаев применяется то же самоек вашему примеру.В остальных 0,000001% случаях это должно произойти, но есть разница в эффективности между некоторыми странными переопределениями операторов и , которые компилятор не может преобразовать один в другой.Действительно, 0,000001% преувеличивает случай и упоминается только потому, что я почти уверен, что если бы я попытался достаточно усердно, я мог бы написать что-то, где один был бы менее эффективным, чем другой.Обычно люди не очень стараются это сделать.
Если вы когда-нибудь посмотрите на свой собственный код в отражателе, вы, вероятно, найдете несколько случаев, когда он выглядит совсем не так, как написанный вами код.Причина этого заключается в том, что это обратный инжиниринг IL вашего кода, а не самого вашего кода, и действительно одна вещь, которую вы часто найдете, это такие вещи, как if(var == true)
или if(var != false)
, превращающиеся в if(var)
или даже вif(!var)
с перевернутыми блоками if
и else
.
Посмотрите глубже, и вы увидите, что еще больше изменений сделано в том, что существует более одного способа убрать одного и того же кота.В частности, интересно посмотреть, как операторы switch
преобразуются в IL;иногда он превращается в эквивалент множества if-else if
операторов, а иногда он превращается в поиск в таблице переходов, которые можно было бы сделать, в зависимости от того, что казалось более эффективным в рассматриваемом случае.
Посмотрите еще глубже, и другие изменения будут внесены, когда он будет скомпилирован в собственный код.
Я не собираюсь соглашаться с теми, кто говорит о "преждевременной оптимизации" только потому, что вы спрашиваете о разнице в производительности между двумяразные подходы, потому что знание таких различий - хорошая вещь, преждевременно (только по определению) использовать эти знания преждевременно.Но изменение, которое будет скомпилировано, не является ни преждевременным, ни оптимизацией, это просто нулевое изменение.