Java: 尽可能使用堆栈变量

2016-02-19 18:58 15 1 收藏

今天图老师小编给大家展示的是Java: 尽可能使用堆栈变量,精心挑选的内容希望大家多多支持、多多分享,喜欢就赶紧get哦!

【 tulaoshi.com - 编程语言 】

假如您频繁存取变量,就需要考虑从何处存取这些变量。变量是 static 变量,还是堆栈变量,或者是类的实例变量?变量的存储位置对存取它的代码的性能有明显的影响?例如,请考虑下面这段代码:
  
  class StackVars
  {
   private int instVar;
   private static int staticVar;
   
   //存取堆栈变量
   void stackAccess(int val)
   {
     int j=0;
     for (int i=0; ival; i++)
       j += 1;
   }
   
   //存取类的实例变量
   void instanceAccess(int val)
   {
     for (int i=0; ival; i++)
       instVar += 1;
   }  
   
   //存取类的 static 变量
   void staticAccess(int val)
   {
     for (int i=0; ival; i++)
       staticVar += 1;
   }
  }    
  
  这段代码中的每个方法都执行相同的循环,并反复相同的次数。唯一的不同是每个循环使一个不同类型的变量递增。方法 stackAccess 使一个局部堆栈变量递增,instanceAccess 使类的一个实例变量递增,而 staticAccess 使类的一个 static 变量递增。
  
  instanceAccess 和 staticAccess 的执行时间基本相同。但是,stackAccess 要快两到三倍。存取堆栈变量如此快是因为,JVM 存取堆栈变量比它存取 static 变量或类的实例变量执行的操作少。请看一下为这三个方法生成的字节码:
  
  Method void stackAccess(int)
    0 iconst_0         //将 0 压入堆栈。
    1 istore_2         //弹出 0 并将它存储在局部分变量表中索引为 2 的位置 (j)。
    2 iconst_0         //压入 0。
    3 istore_3         //弹出 0 并将它存储在局部变量表中索引为 3 的位置 (i)。
    4 goto 13          //跳至位置 13。
    7 iinc 2 1         //将存储在索引 2 处的 j 加 1。
   10 iinc 3 1         //将存储在索引 3 处的 i 加 1。
   13 iload_3          //压入索引 3 处的值 (i)。
   14 iload_1          //压入索引 1 处的值 (val)。
   15 if_icmplt 7      //弹出 i 和 val。假如 i 小于 val,则跳至位置 7。
   18 return           //返回调用方法。
   
  Method void instanceAccess(int)
    0 iconst_0         //将 0 压入堆栈。
    1 istore_2         //弹出 0 并将它存储在局部变量表中索引为 2 的位置 (i)。
    2 goto 18          //跳至位置 18。
    5 aload_0          //压入索引 0 (this)。
    6 dup              //复制堆栈顶的值并将它压入。
    7 getfield #19 Field int instVar
                       //弹出 this 对象引用并压入 instVar 的值。
   10 iconst_1         //压入 1。
   11 iadd             //弹出栈顶的两个值,并压入它们的和。
   12 putfield #19 Field int instVar
                       //弹出栈顶的两个值并将和存储在 instVar 中。
   15 iinc 2 1         //将存储在索引 2 处的 i 加 1。
  

来源:https://www.tulaoshi.com/n/20160219/1619684.html

延伸阅读
一、类的初始化 对于类的初始化:类的初始化一般只初始化一次,类的初始化主要是初始化静态成员变量。 类的编译决定了类的初始化过程。 编译器生成的class文件主要对定义在源文件中的类进行了如下的更改: 1)       先按照静态成员变量的定义顺序在类内部声明成员变量。 2)     ...
  我们知道,Java的数据类型分为三大类,即布尔型、字符型和数值型,而其中数值型又分为整型和浮点型;相对于数据类型,Java的变量类型为布尔型boolean;字符型char;整型byte、short、int、long;浮点型float、double。其中四种整型变量和两种浮点型变量分别对应于不同的精度和范围。此外,我们还经常用到两种类变量,即String和Date。对...
标签: PHP
      自PHP4.1.0以后将HTTP_GET_VARS使用GET变量来保存,GET的变量主要来自以下的方法 对服务器以获取资料信息为请求方法的例如,URL,使用FORM的METHOD为GET方式。这样所有的请求变量将通过 URL传递给服务器,服务器根据配置调用相关的解释器来处理这些GET出来的变量。        ...
?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />   Reflection 是 Java 程序开发语言的特征之一,它答应运行中的 Java 程序对自身进行检查,或者说“自审”,并能直接操作程序的内部属性。例如,使用它能获得 Java 类中各成员的名称并显示出来。 Java 的这一能力在实际应用中也许用得不是...
在极大程度上,为你的类(包括类模板)和函数(包括函数模板)提供正确的定义是战斗的要害性部分。一旦你得到正确的结果,相应的实现很大程度上就是直截了当的。但是仍然有一些注重事项需要当心。过早地定义变量会对性能产生拖累。过度使用强制转换会导致缓慢的,难以维护的,被微妙的 bug 困扰的代码。返回一个类内部构件的句柄会破坏封装...

经验教程

726

收藏

48
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部