news 2026/10/26 9:31:36

两段Java程序的效率

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
两段Java程序的效率

这是很多年前的一篇旧闻,我把它格式调整了一下:

// 代码1 public class Obj { private int i; public int getI() { return i; } public void setI(int i) { this.i = i; } } // 代码2 List result2 = new ArrayList(); Obj o = null; for (int i = 0; i < 10; i++) { o = new Obj(); o.setI(i); result2.add(o); } // 代码3 List result3 = new ArrayList(); for (int i = 0; i < 10; i++) { Obj o = new Obj(); o.setI(i); result3.add(o); }

很多人的结论如下;

1)代码2比代码3的效率高;

2)代码2的可维护性不如代码3,因为变量作用域扩大了。

其实结论1)是错误的。

第2段代码反汇编及说明:
-----------------------------------------------------------------------
0: new #3; //new ArrayList()
3: dup //将新创建的ArrayList的引用复制并压入栈
4: invokespecial #4; //编译器插入的ArrayList初始化方法:ArrayList."<init>"
7: astore_1 //局部变量赋值:result2 = new ArrayList();
8: aconst_null //局部变量赋值:o = null
9: astore_2

10: iconst_0 //局部变量赋值:i = 0
11: istore_3
12: iload_3 //比较i和10
13: bipush 10
15: if_icmpge 45 //如果i >= 10 函数返回
18: new #5; //new Obj()
21: dup //将新创建的Obj的引用复制并压入栈
22: invokespecial #6; //编译器插入的Obj初始化方法 Method "<init>"
25: astore_2 //局部变量赋值:o = new Obj();
26: aload_2 //准备调用参数栈,取出局部变量的引用并压栈: o
27: iload_3 //准备调用参数栈,取出局部变量的值并压栈:i
28: invokevirtual #7; //方法调用:o.set(i);
31: aload_1 //取出局部变量的引用并压栈: result2
32: aload_2 //取出局部变量的引用并压栈: o
33: invokeinterface #8, 2; //调用List.add()方法: result2.add(o);
38: pop
39: iinc 3, 1 //i++
42: goto 12 //回到for循环头
45: return //函数返回
-----------------------------------------------------------------------

第3段代码反汇编及说明:
-----------------------------------------------------------------------
0: new #3; //new ArrayList()
3: dup /将新创建的ArrayList的引用复制并压入栈
4: invokespecial #4; //编译器插入的ArrayList初始化方法:ArrayList."<init>"
7: astore_1 /局部变量赋值:result3 = new ArrayList();
8: iconst_0 //局部变量赋值:i = 0
9: istore_2
10: iload_2 //比较i和10
11: bipush 10
13: if_icmpge 43 //如果i >= 10 函数返回
16: new #5; //new Obj()
19: dup //将新创建的Obj的引用复制并压入栈
20: invokespecial #6; //编译器插入的Obj初始化方法 Method "<init>"
23: astore_3 //局部变量赋值:o = new Obj();
24: aload_3 //准备调用参数栈,取出局部变量的引用并压栈: o
25: iload_2 //准备调用参数栈,取出局部变量的值并压栈:i
26: invokevirtual #7; //方法调用:o.set(i);
29: aload_1 //取出局部变量的引用并压栈: result3
30: aload_3 //取出局部变量的引用并压栈: o
31: invokeinterface #8, 2; //调用List.add()方法: result3.add(o);
36: pop
37: iinc 2, 1 //i++
40: goto 10 //回到for循环头
43: return //函数返回
-----------------------------------------------------------------------

小结:
1、代码2效率显然不如代码3,红色那两行是多余的。
2、代码2可维护性比较差,前面有说明。

代码2与代码3的差异,除了多了那两句,就是局部变量的索引顺序不同,循环体的反汇编也是完全一样的。所以,代码2各方面都不如代码3,一般推荐3的写法。这与大多数人日常编码习惯是一致的:)

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/26 9:31:27

马尾辫扎法全解析:从分区到固定的核心技巧

1. 先把马尾辫当成一个真问题来拆解1.1 为什么马尾几乎是所有编发的底层能力马尾辫&#xff0c;英文标题里写的就是 ponytail。很多朋友觉得它是所有发型里最简单的&#xff0c;不需要学&#xff0c;随手一抓就是。但真到了现场你会发现问题远没这么简单&#xff1a;有人扎完头…

作者头像 李华
网站建设 2026/10/26 9:30:59

SVM与朴素贝叶斯算法原理及实战对比

1. 支持向量机与朴素贝叶斯算法解析 在机器学习领域&#xff0c;支持向量机(SVM)和朴素贝叶斯(Naive Bayes)是两种经典且广泛应用的算法。它们分别代表了不同的学习范式&#xff1a;SVM基于最大间隔原则进行判别式学习&#xff0c;而朴素贝叶斯则基于贝叶斯定理进行生成式建模。…

作者头像 李华
网站建设 2026/10/26 9:30:55

DPT深度估计模型:Transformer在计算机视觉中的应用

1. DPT深度估计模型架构解析 DPT&#xff08;Dense Prediction Transformer&#xff09;是近年来计算机视觉领域将Transformer架构成功应用于密集预测任务的代表性工作。与传统的CNN-based深度估计方法相比&#xff0c;DPT通过纯Transformer结构实现了从单张RGB图像到深度图的端…

作者头像 李华
网站建设 2026/10/26 9:30:42

全国DEM数据TIF使用指南:从分幅校验到省级无缝拼接

简介&#xff1a;本资源为覆盖全国范围的高精度数字高程模型&#xff08;DEM&#xff09;数据集&#xff0c;面向地理信息、遥感测绘、环境科学及城市规划等领域的研究者与GIS初学者。数据以TIFF格式存储&#xff0c;具备无损压缩、支持地理元数据和多层信息等GIS友好特性&…

作者头像 李华
网站建设 2026/10/26 9:30:27

UniApp+Vue高校社团小程序开发实战与优化

1. 项目概述&#xff1a;高校社团管理小程序的技术选型与价值 去年帮本地一所高校升级社团管理系统时&#xff0c;我们放弃了传统的PC端Web方案&#xff0c;转而采用uniappvue技术栈开发微信小程序。这个选择让注册率提升了47%&#xff0c;管理效率提高了60%。微信小程序天然具…

作者头像 李华
网站建设 2026/10/26 9:30:26

SpringBoot高校学生信息化管理系统全栈开发实践

1. 项目概述&#xff1a;SpringBoot高校学生信息化管理系统全栈解决方案 这个基于SpringBoot的高校学生信息化管理系统&#xff08;项目编号9571z&#xff09;是一套覆盖学生全生命周期管理的企业级应用。我在实际开发中发现&#xff0c;传统校园管理系统往往存在模块割裂、数据…

作者头像 李华