比较操作比赋值操作CPU周期更少?C++两种Setter写法及POD差异
带前置判断的Setter是否比直接赋值更高效?
我经常看到两种C++ Setter写法:
第一种(带前置判断):
void class::memberSetter(const type& val) { if (m_member == val) return; m_member = val; }
第二种(直接赋值):
void class::memberSetter(const type& val) { m_member = val; }
想知道第一种写法是否真的有正向效果?还是直接赋值在CPU周期上更高效?另外,针对POD类型和非POD类型,情况会有什么不同?
核心结论
两种写法的优劣完全取决于type的特性以及实际业务场景,没有绝对的“更高效”。
针对POD类型(如int、float、简单结构体)
- 直接赋值几乎总是更优。POD的赋值本质是内存拷贝,速度极快——比如int赋值就是单个CPU周期的事。前置的
==判断需要额外读取两个值做比较,再加上分支判断,反而会多消耗CPU周期,甚至可能因为分支预测失败带来额外性能损耗。 - 极端例外:如果Setter被高频调用且绝大多数传入值都和成员变量相等,判断可能能节省少量内存写入,但这种场景非常罕见,因为POD写入的开销远小于分支判断成本。
针对非POD类型(如std::string、自定义类)
- 带判断的写法往往更有价值:
- 避免不必要的深拷贝:比如
std::string赋值时,若内容不同会触发内存分配和数据拷贝;前置判断能直接跳过整个流程,节省大量开销。即使某些实现对相同值的赋值做了优化,提前判断也能省掉进入赋值函数的额外开销。 - 避免副作用:如果自定义类的赋值运算符重载了复杂逻辑(比如触发信号、更新缓存、修改关联状态),前置判断能在值未变化时避免这些冗余操作,既省性能又防逻辑混乱。
- 避免不必要的深拷贝:比如
- 注意:如果非POD类型的
==运算符本身开销极大(比如需要遍历大量成员做比较),就要权衡——比如一个包含数十个成员的类,==的开销可能比直接赋值还大,这时候直接赋值反而更划算。
总结建议
- POD类型:优先直接赋值,除非有明确的性能测试数据证明判断能带来提升。
- 非POD类型:优先加判断,尤其是当赋值操作有明显开销或副作用时;若
==判断本身成本过高,再考虑直接赋值。
内容的提问来源于stack exchange,提问作者Redman
相关产品推荐
相关产品推荐

