时月oe 2023-07-08 11:37 采纳率: 44.4%
浏览 20
已结题

关于Java对于for循环的优化问题

在代码大全中看到了一个观点:越繁忙的循环应该放在最内部,可以减少初始化的次数,随即我在Java中进行验证,但是结果却恰恰相反

public class Main {
    public static void main(String[] args) {
        int sum = 0;
        final int big = 10000000;
        final int small = 10;
        long l = System.nanoTime();
        for(int i = 0;i < big;i++){
            for(int j = 0;j < small;j++){
                //sum++;
            }
        }
        System.out.println("big out : " + (System.nanoTime() - l));

        l = System.nanoTime();
        for(int i = 0;i < small;i++){
            for(int j = 0;j < big;j++){
                //sum++;
            }
        }
        System.out.println("big in  : " + (System.nanoTime() - l));
    }
}

最终的打印结果为:

big out : 5119088
big in  : 15178535

明显是for循环在外部的更快,看了很多帖子也没有头绪,请问这是因为JVM对于for循环的优化导致的吗?

  • 写回答

2条回答 默认 最新

  • threenewbee 2023-07-08 11:45
    关注

    循环到底谁放在里面谁放在外面,主要是考虑2个问题:
    (1)分支预测命中率,如果小循环放在内侧,意味着一会儿循环,一会儿跳出循环,会让分支预测不准,导致一些开销
    (2)缓存命中率,比如说对于二维数组操作,按照行来操作,每个内循环内再按照列来操作,这样其实是连续访问内存的,反过来的话,就跳跃存取内存,那么缓存失败的概率比较高,导致开销
    但是这个都是经验之谈,硬件的发展是突飞猛进的。比如说在代码大全编写的2000年,Pentium III处理器只有16KB一级缓存,P4更是减少到8KB,而现在的处理器甚至有64KB一级缓存了,二级缓存更不用说了。
    而现在的JVM和CPU,也会根据大多数的代码,用大数据的方式做了优化,因此程序员刻意使用某种技巧的意义越来越小。
    你这种空循环的测试,并不具有任何典型性。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 7月16日
  • 已采纳回答 7月8日
  • 创建了问题 7月8日

悬赏问题

  • ¥15 c++ gmssl sm2验签demo
  • ¥15 关于模的完全剩余系(关键词-数学方法)
  • ¥15 有没有人懂这个博图程序怎么写,还要跟SFB连接,真的不会,求帮助
  • ¥15 关于移动机器人坐标计算
  • ¥30 模拟电路 logisim
  • ¥15 PVE8.2.7无法成功使用a5000的vGPU,什么原因
  • ¥15 is not in the mmseg::model registry。报错,模型注册表找不到自定义模块。
  • ¥15 安装quartus II18.1时弹出此error,怎么解决?
  • ¥15 keil官网下载psn序列号在哪
  • ¥15 想用adb命令做一个通话软件,播放录音