真奇怪,为啥我的方法加了final修饰符,效率反而降低了

昵称是可以中文吗 2017-01-28 10:48:11
网上都说加了final,会提高效率,为何我加了反而效率降低了?
我写的测试类如下:
ClassTest1:

public class ClassTest1 {
public final String getName() {
return name;
}

public final void setName(String name) {
this.name = name;
}

private String name;
}

ClassTest2:

public class ClassTest2 {
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

private String name;
}


测试的main方法如下:

public static void main(String[] args) {
ClassTest1 ct1=new ClassTest1();
ClassTest2 ct2=new ClassTest2();
Long t1=System.currentTimeMillis();
for (int i = 0; i <1000000 ; i++) {
ct1.getName();
}
Long t2=System.currentTimeMillis();
for (int i = 0; i <1000000 ; i++) {
ct2.getName();
}
Long t3=System.currentTimeMillis();
System.out.println("add final decorate cost time:"+(t2-t1));
System.out.println("not add final decorate cost time:"+(t3-t2));
}

为啥加了final的时间反而更长了
...全文
706 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
aCat95 2017-02-13
  • 打赏
  • 举报
回复
目前来看 final可以提升性能已经是个伪命题了 所以不要再花时间在这个上了
忆寒哥哥耶 2017-02-07
  • 打赏
  • 举报
回复
java自带常量优化机制
  • 打赏
  • 举报
回复
这个例子运行时间应该差不多吧。 加载类的时候,虚拟机会生成方法表,当运行时,查询方法表找到方法调用。
darkread 2017-02-06
  • 打赏
  • 举报
回复
这个结果是可以理解的 有final: 没有虚函数表,直接调用,最快 无final: 普通虚函数,那么正常速度,中间 有final子类:因为没有虚函数表,需要转换成父类,较慢 无final子类: 因为虚函数,从虚函数表找父类的getName,最慢 当然虚函数表的描述是有一定限制的,比如HotSpot VM确实是有为Java类生成vtable的,但是其他jvm虚拟机不一定就有,但是处理虚函数的方法基本一致,我们可以统一理解。
darkread 2017-02-06
  • 打赏
  • 举报
回复
我测试过无论如何执行,调换两个顺序,多次单个执行取平均,效率是 有final>无final>有final的子类, 如果只有xx.getName(),没有做对该结果的操作,那么会被优化掉。近乎0消耗,我1000000级别的循环,System.currentTimeMillis()差值是0
little_how 2017-02-06
  • 打赏
  • 举报
回复
很多性能的说法都是过时的,现在jit优化,一般都是想要搬到内联; 给你个参考资料,很新的,暂时没过时; http://mp.weixin.qq.com/s?__biz=MzI3MzEzMDI1OQ==&mid=2651815337&idx=1&sn=8e846e11e908735a5175c9eacb642329&chksm=f0dc2bd5c7aba2c3fafa009019cc475a9f118178e72ea88511aacb8df5b9aca3e7e226d8d7f2&mpshare=1&scene=1&srcid=1029dG5St1iVWezgCkYGM5KJ#rd
darkread 2017-02-06
  • 打赏
  • 举报
回复
引用 10 楼 SCAUSCNU 的回复:
[quote=引用 7 楼 darkread 的回复:] 我测试过无论如何执行,调换两个顺序,多次单个执行取平均,效率是 有final>无final>有final的子类, 如果只有xx.getName(),没有做对该结果的操作,那么会被优化掉。近乎0消耗,我1000000级别的循环,System.currentTimeMillis()差值是0
按我的代码测试,基本是先执行的会吃亏一点哦[/quote] 颠倒顺序我也测试,差不多。因为两者差距1倍左右,微量差距不明显。如果要进行公平测试,可以先对有final、无final,然后按照有final循环、无final循环,反复跑100组,看平均成绩。因为,目前jvm的垃圾收集是在1ms左右,因此单次循环1秒2ms以上基本可以抹平垃圾收集的暂停时间了。 我在win7 64 JDK1.8下测试。
  • 打赏
  • 举报
回复
引用 7 楼 darkread 的回复:
我测试过无论如何执行,调换两个顺序,多次单个执行取平均,效率是 有final>无final>有final的子类, 如果只有xx.getName(),没有做对该结果的操作,那么会被优化掉。近乎0消耗,我1000000级别的循环,System.currentTimeMillis()差值是0
按我的代码测试,基本是先执行的会吃亏一点哦
逗泥丸的平方 2017-02-04
  • 打赏
  • 举报
回复
倒过来试试 这种测试是不公平的. 在前面执行的应该会吃亏一些
darkread 2017-02-03
  • 打赏
  • 举报
回复
ct2.getName(); 也改成 x+= ct2.getName();代码是手工打的,有点问题,测试代码在内网不能拷贝出来。 我是jdk 1.8
darkread 2017-02-03
  • 打赏
  • 举报
回复
为了防止优化,我改了你的代码

       String x = "";
       for (int i = 0; i <1000000 ; i++) {
           x+= ct1.getName();
        }
        Long t2=System.currentTimeMillis();
        System.out.println("add final decorate cost time:"+(t2-t1));
        x="";
        t1 = =System.currentTimeMillis();
        for (int i = 0; i <1000000 ; i++) {
            ct2.getName();
        }
        t2 = =System.currentTimeMillis();
       System.out.println("not add final decorate cost time:"+(t2-t1));
每次都是带final的快,快50%,除非我继承一个ClassTest1,那么这个测试会比 ClassTest2慢一倍
  • 打赏
  • 举报
回复
引用 4 楼 u014689192 的回复:
final其实对性能影响吧。。
没影响
  • 打赏
  • 举报
回复
final其实对性能影响吧。。
  • 打赏
  • 举报
回复
引用 2 楼 darkread 的回复:
ct2.getName(); 也改成 x+= ct2.getName();代码是手工打的,有点问题,测试代码在内网不能拷贝出来。 我是jdk 1.8
额,难道是因为优化的原因?JVM应该可以禁止优化的吧

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧