Имеет ли смысл проверять, отличаются ли значения в сеттере

Помню, я где-то видел (возможно, в Гитубе) пример, подобный этому в сеттер:

void MyClass::setValue(int newValue)
{
 if (value != newValue) {
 value = newValue;
 }
}

Для меня это не имеет большого смысла, но мне интересно, улучшает ли он производительность.

4 ответа

Чем глубже конвейер команд (и он по крайней мере глубже и глубже на платформе Intel), тем выше стоимость неверное предсказание отрасли.

Когда ветка ошибочно предсказывает, некоторые инструкции из неверно предсказанного путь все еще проходит по трубопроводу. Все работы, выполненные на этих инструкции теряются, поскольку они не были бы выполнены, если бы ветвь правильно предсказана

Итак, да, добавив код if int, он может повредить производительность. Запись будет кэшироваться L1, возможно, в течение длительного времени. Если запись должна быть видимой, тогда операция должна быть блокирована для начала.


Это не имеет смысла для scalar types, но может иметь смысл для некоторых типов user-defined (так как тип может быть действительно "большим", или его оператор присваивания может выполнять некоторую "трудную" работу).


Единственный способ, который вы действительно можете сказать, - это фактически протестировать различные альтернативы (бенчмаркинг и/или профилирование кода). Разный компилятор, разные процессоры и другой код, вызывающий его, будут иметь большое значение.

В общем, и для "простых" типов данных (int, ******, char, указатели и т.д.) это не имеет смысла. Это просто сделает код более длинным и сложным для процессора [по крайней мере, если компилятор выполнит то, что вы просите об этом), он может понять, что "это не имеет никакого смысла, удалите эту проверку - я не буду полагаться на что tho '- компиляторы часто умнее вас, но усложняет жизнь, поскольку компилятор почти никогда не приводит к улучшению кода].

Edit: Кроме того, только разумно сравнивать вещи, которые можно легко сравнить. Если сложно сравнивать данные в случае, когда они равны (например, длинные строки берут много чтений из обеих строк, если они равны [или строки, которые начинаются одинаково, и отличаются только в последних нескольких символах) Таким образом, очень мало экономии. То же самое относится к классу с группой членов, которые часто почти одинаковы, но одного или двух полей нет и т.д. С другой стороны, если у вас есть "клиент" data ", у которого есть целостный идентификатор клиента, который должен быть уникальным, тогда сравнение только идентификатора клиента будет" дешевым ", но копирование имени, адреса, номера телефона и других данных клиента будет дорогостоящим. [Конечно, в этом случае, почему это не (умный) указатель или ссылка?]. End Edit.

Если данные "разделяются" между разными процессорами (несколько потоков обращаются к тем же данным), то это может помочь немного [в частности, если это значение часто читается и часто записывается с тем же значением, что и раньше]. Это связано с тем, что "выбивание" старого значения из других кэшей процессора дорого, и вы только хотите это сделать, если вы НАСТОЯТЕЛЬНО что-то измените.

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


Эта схема распространена в Qt, где API основан на сигналах и слотах. Этот шаблон помогает избежать бесконечного цикла в случае циклических соединений.

В вашем случае, когда сигналов нет, этот код только убивает производительность, как указано @remus-rusanu и @mats-petersson.

licensed under cc by-sa 3.0 with attribution.