You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java长循环中冗余赋值与赋值前检查的性能开销对比

长循环场景下冗余赋值与条件判断的资源开销对比

基础场景:局部变量操作

注:第二个示例循环次数写为10_000应为笔误,以下按二者均循环10万次、else分支命中5万次的前提对比:

实现1:else分支直接赋值

int count = 0;
for(int i=0; i<100_000; i++){
    if (...) {
        count++;
        doLogic(count); // logic is strictly related with count
    } else {
        count = 0;  //50000次冗余赋值
    }
}

实现2:赋值前先做条件判断

int count = 0;
for(int i=0; i<100_000; i++){
    if (...) {
        count++;
        doLogic(count); // logic is strictly related with count
    } else {
        if(count > 0) { // 50000次条件检查
            count = 0;
        }
    }
}

开销对比结论

局部变量场景下,实现1(直接冗余赋值)的开销更低:

  • 基础类型int的局部变量存储在栈空间或者CPU寄存器上,赋值操作是单周期CPU指令,哪怕冗余执行,开销几乎可以忽略
  • 实现2每次else分支都要额外执行「读取count值 + 数值比较」两个操作,哪怕CPU分支预测命中率100%,也比直接赋值多了运算步骤;如果count的变化规律不规则导致分支预测失败,还会触发CPU流水线冲刷,额外开销会进一步拉大
  • 内存层面二者没有差异,都只占用固定的栈空间存储count变量,没有额外内存占用

延伸场景:count封装在Spring单例对象中

这种场景下操作的不再是栈上的局部变量,而是堆内存中单例对象的成员变量,同时多了方法调用的开销,二者的开销差异会发生变化,没有绝对的优劣,要看业务场景中count>0在else分支中的出现概率:

  • 如果count>0的概率很低(比如100次else分支里只有1次需要重置):实现2更划算,少量的getCount()读操作+比较的开销,远低于大量冗余的resetCount()写操作开销
  • 如果count>0的概率很高(比如超过30%的else分支都需要重置):实现1更划算,省去了每次getCount()的方法调用、堆内存读取、比较的开销,直接调用resetCount()反而总开销更低
    额外注意如果count加了volatile修饰保证多线程可见性,堆读写的开销会进一步提升,更建议根据命中概率选择方案。

内容的提问来源于stack exchange,提问作者Ermal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 21:27:00