验证设置器中的值是否不同是否有意义

时间:2013-05-09 21:28:33

标签: c++ performance

我记得我在某个地方(可能是在Github)看到了这样一个例子:

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

对我而言,它没有多大意义,但我想知道它是否会带来任何性能提升。

4 个答案:

答案 0 :(得分:7)

对于scalar types没有意义,但对于某些user-defined类型可能有意义(因为类型可能真的“大”或者它的赋值运算符可以做一些“硬”工作)。 / p>

答案 1 :(得分:4)

您可以真正告诉的唯一方法是实际测试不同的替代方案(基准测试和/或分析代码)。不同的编译器,不同的处理器和调用它的不同代码将产生很大的不同。

一般而言,简单"简单"数据类型(int,double,char,pointers等),它没有意义。它只会让处理器的代码变得更长,更复杂[至少如果编译器完成你所要求的那样 - 它可能会意识到"这没有任何意义,让我们删除这个检查 - 我不会依赖那个' - 编译器通常比你聪明,但是让编译器的生活变得更加困难,几乎不会导致更好的代码]。

编辑:此外,只有比较易于比较的事物才有意义。如果在数据相等的情况下比较数据很困难(例如,如果两个字符串相等,则长字符串会从两个字符串中读取大量数据[或者字符串开始相同,并且仅在最后几个字符]。所以保存很少。这同样适用于一组通常几乎全部相同的成员,但是一两个字段不是,等等。另一方面,如果你有一个"客户数据"类,它具有必须唯一的整数客户ID,然后比较客户ID将是"便宜",但复制客户名称,地址,电话数字和客户的其他数据将是昂贵的。[当然,在这种情况下,为什么它不是(智能)指针或参考?]。结束编辑。

如果数据是"共享"在不同的处理器之间(多个线程访问相同的数据),它可能会有所帮助[特别是如果这个值经常被读取,并且通常用与之前相同的值写入]。这是因为"踢出了#34;来自其他处理器缓存的旧值非常昂贵,如果您实际更改某些内容,您只想这样做。

当然,当你在处理你知道完全处于性能热路径最前沿的代码时,担心性能是有道理的。在其他任何地方,使代码尽可能易读和清晰简洁始终是最佳选择 - 这通常也会使编译器更能够确定实际发生的情况并确保最佳的优化结果。

答案 2 :(得分:4)

指令流程越深(至少在英特尔平台上越来越深),branch misprediction的成本越高。

  

当某个分支机构误预测时,某些指示来自错误预测   路径仍在通过管道。所有工作都在这些上进行   指令被浪费,因为他们不会被执行了   分支被正确预测

所以是的,在代码中添加if int实际上会损害性能。写入将是L1缓存,可能很长一段时间。如果写入必须是可见的,则操作必须互锁才能开始。

答案 3 :(得分:2)

此模式在Qt中很常见,其中API高度基于signals & slots。这种模式有助于在循环连接的情况下避免无限循环。

在你的情况下,如果没有信号,这段代码只会杀死性能,正如@ remus-rusanu和@ mats-petersson所指出的那样。