热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ii快java_Java之深入JVM(1)由i++和++i的执行速度所想到的

iii--1i1以上的四句代码,问那句的执行速度更快?对于CC程序员来说,可能首先想到的就是i和i要比其他两者要快一些,但是在Java中是

48304ba5e6f9fe08f3fa1abda7d326ab.png

i++++i

i-=-1i+=1

48304ba5e6f9fe08f3fa1abda7d326ab.png

以上的四句代码,问那句的执行速度更快?

对于C/C++程序员来说,可能首先想到的就是i++和++i要比其他两者要快一些,但是在Java中是不是这样的呢?

我们可以对他进行一些分析,首先当然想到的是对这些语句利用Java的System.currentTimeMillis()计算单个语句运行很多次(如10亿次)后的时间,然后作比较.

例如这样:

测试环境:(1)Windows XP sp3 (2)JDK "1.6.0_07"   Client VM (build 10.0-b23, mixed

mode, sharing)

9310e85a14af99de4811ff4c77f1f911.png

24a924a57ba6b3f2b51fc9edb7ea4186.pngCodepublicclassIncrement {publicintpreIncrement() {inti=0;++i;returni;

}publicintpostIncrement() {inti=0;

i++;returni;

}publicintnegative() {inti=0;

i-=-1;returni;

}publicintplusEquals() {inti=0;

i+=1;returni;

}publicstaticvoidmain(String[] args) {

Increment in&#61;newIncrement();longstart&#61;System.currentTimeMillis();for(inti&#61;0; i<1000000000;

i&#43;&#43;) {

in.preIncrement();

}

System.out.println("preIncrement:"&#43;(System.currentTimeMillis()-start));

start&#61;System.currentTimeMillis();for(inti&#61;0; i<1000000000;

i&#43;&#43;) {

in.postIncrement();

}

System.out.println("postIncrement:"&#43;(System.currentTimeMillis()-start));

start&#61;System.currentTimeMillis();for(inti&#61;0; i<1000000000;

i&#43;&#43;) {

in.negative();

}

System.out.println("negative:"&#43;(System.currentTimeMillis()-start));

start&#61;System.currentTimeMillis();for(inti&#61;0; i<1000000000;

i&#43;&#43;) {

in.plusEquals();

}

System.out

.println("plusEquals:"&#43;(System.currentTimeMillis()-start));

}

}

运行结果&#xff0c;发现四次结果都不一样但是差别极其微小&#xff0c;如图:

026362f5d6206147052bc7d11d319a10.png

但是这样我们是不是就可以说&#xff0c;这四个语句的运行在Java中是有差别或者是无差别的呢&#xff1f;当然不能这样去说&#xff0c;这个程序的具体运行还受限于当前机器的所运行的其他程序以及JVM中的JIT引擎对执行代码的优化等。

其实一个比较合理的办法利用Javap反汇编这个文件&#xff0c;去看看反汇编后各个方法所生成的字节码&#xff0c;由于JVM在运行的时候就是执行这些中间代码&#xff0c;所以比较能够说明问题.

7ea6adb06a97add062cc42d178f02d3c.png

然后我运行javap –c –v

com.jni.test.tracker.object.Increment去反汇编这个代码&#xff0c;得到了preIncrement&#xff0c;postIncrement&#xff0c;negative&#xff0c;plusEquals方法各自的字节码如下&#xff1a;

public intpreIncrement();

Code:

Stack&#61;1, Locals&#61;2, Args_size&#61;1

0: iconst_01: istore_12: iinc 1, 1

5: iload_16: ireturn

LineNumberTable:

line5: 0line6: 2line7: 5LocalVariableTable:

Start Length Slot Name Signature0 7 0 this Lcom/jni/test/tracker/object/Increment;2 5 1i Ipublic intpostIncrement();

Code:

Stack&#61;1, Locals&#61;2, Args_size&#61;1

0: iconst_01: istore_12: iinc 1, 1

5: iload_16: ireturn

LineNumberTable:

line11: 0line12: 2line13: 5LocalVariableTable:

Start Length Slot Name Signature0 7 0 this Lcom/jni/test/tracker/object/Increment;2 5 1i Ipublic intnegative();

Code:

Stack&#61;1, Locals&#61;2, Args_size&#61;1

0: iconst_01: istore_12: iinc 1, 1

5: iload_16: ireturn

LineNumberTable:

line17: 0line18: 2line19: 5LocalVariableTable:

Start Length Slot Name Signature0 7 0 this Lcom/jni/test/tracker/object/Increment;2 5 1i Ipublic intplusEquals();

Code:

Stack&#61;1, Locals&#61;2, Args_size&#61;1

0: iconst_01: istore_12: iinc 1, 1

5: iload_16: ireturn

LineNumberTable:

line23: 0line25: 2line26: 5LocalVariableTable:

Start Length Slot Name Signature0 7 0 this Lcom/jni/test/tracker/object/Increment;2 5 1 i I

令人惊讶的是&#xff0c;虽然这四个方法是不一样的&#xff0c;但是经过Java编译器优化后&#xff0c;我们发现生成的四个方法的bytecode实际都是一样的。

下面简单讲解一下这几句bytecode

iconst_0:将int类型的值0压入栈

istore_1: 从栈中弹出int类型值&#xff0c;然后将其存到位置为0的局部变量中

iinc 1,1 : 为局部变量中位置为1的int数 加1

iload_1 : 将局部变量中位置为1的int变量入栈

ireturn : 从栈中弹出int类型值。



推荐阅读
  • 零拷贝技术是提高I/O性能的重要手段,常用于Java NIO、Netty、Kafka等框架中。本文将详细解析零拷贝技术的原理及其应用。 ... [详细]
  • 本文详细介绍了Java反射机制的基本概念、获取Class对象的方法、反射的主要功能及其在实际开发中的应用。通过具体示例,帮助读者更好地理解和使用Java反射。 ... [详细]
  • 我有一个从C项目编译的.o文件,该文件引用了名为init_static_pool ... [详细]
  • 2020年9月15日,Oracle正式发布了最新的JDK 15版本。本次更新带来了许多新特性,包括隐藏类、EdDSA签名算法、模式匹配、记录类、封闭类和文本块等。 ... [详细]
  • Hadoop的文件操作位于包org.apache.hadoop.fs里面,能够进行新建、删除、修改等操作。比较重要的几个类:(1)Configurati ... [详细]
  • 本文回顾了作者初次接触Unicode编码时的经历,并详细探讨了ASCII、ANSI、GB2312、UNICODE以及UTF-8和UTF-16编码的区别和应用场景。通过实例分析,帮助读者更好地理解和使用这些编码。 ... [详细]
  • [转]doc,ppt,xls文件格式转PDF格式http:blog.csdn.netlee353086articledetails7920355确实好用。需要注意的是#import ... [详细]
  • JVM钩子函数的应用场景详解
    本文详细介绍了JVM钩子函数的多种应用场景,包括正常关闭、异常关闭和强制关闭。通过具体示例和代码演示,帮助读者更好地理解和应用这一机制。适合对Java编程和JVM有一定基础的开发者阅读。 ... [详细]
  • 本文总结了Java初学者需要掌握的六大核心知识点,帮助你更好地理解和应用Java编程。无论你是刚刚入门还是希望巩固基础,这些知识点都是必不可少的。 ... [详细]
  • 【妙】bug称它为数组越界的妙用
    1、聊一聊首先跟大家推荐一首非常温柔的歌曲,跑步的常听。本文主要把自己对C语言中柔性数组、零数组等等的理解分享给大家,并聊聊如何构建一种统一化的学习思想 ... [详细]
  • Flutter 2.* 路由管理详解
    本文详细介绍了 Flutter 2.* 中的路由管理机制,包括路由的基本概念、MaterialPageRoute 的使用、Navigator 的操作方法、路由传值、命名路由及其注册、路由钩子等。 ... [详细]
  • WinMain 函数详解及示例
    本文详细介绍了 WinMain 函数的参数及其用途,并提供了一个具体的示例代码来解析 WinMain 函数的实现。 ... [详细]
  • 【刷题篇】Java 不用Math.sqrt() 如何求一个数的平方根
    题目:在不用Math.sqrt()方法中如何求解一个大于1的数的平方根题解一、牛顿迭代法计算x2n的解,令f(x)x2-n,相当于求解f( ... [详细]
  • 在多线程并发环境中,普通变量的操作往往是线程不安全的。本文通过一个简单的例子,展示了如何使用 AtomicInteger 类及其核心的 CAS 无锁算法来保证线程安全。 ... [详细]
  • 本文主要探讨了Java中处理ActionEvent事件的接口,以及一些常见的编程问题和解决方案,包括方法重载、成员变量访问、镜片质量检测等。 ... [详细]
author-avatar
汪健宜婉瑜
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有