PpLK: |Practical Java| Chapter 4 Performance (性能) (二)

来源:互联网 发布:windows10怎么安装软件 编辑:程序博客网 时间:2024/05/01 08:40
|Practical Java| Chapter 4   Performance (性能) (二)
35>   尽可能使用 Stack 变量
         JVM是一种 Stack - based 虚拟机, 因此在访问和操纵 Stack data时性能最
             佳. 程序中所有的 local 变量都会被放在一个local 变量表中, 并于Java
             operand 中操纵, 从而获得很好的性能.
        而访问static 变量或者 instance 变量的代价则高出许多, 因为JVM不得不
             使用更耗时的 opcode, 从constant pool(常量池)中访问她们.
        constant pool  ---->  保存着 symbolic references, 指向所有型别 / 值域, 以
             及每一个型别所使用的所有方法.

36>  使用static / final 和private 函数以促成 inlining
        为了让函数成为 Inlining 候选者, 必须将她们声明为private / static 或者
               final. 此类函数可以被 statically resolved, 而不是dynamic resolution.
               同时也存在一些缺点:  这些函数无法通过subclassing 进行扩展.
        当一个函数inline 后就不再需要负担函数调用的额外开销, 所以在被多次
               调用的情况下, 其性能的提升越明显.

37>   Instance变量的初始化一次就好
         对于面向对象系统而言,程序很多时间都花在对象的creating 和destroying
         上, 因此让construct 尽可能高效对程序十分有益.
        
         Java对于 Instance 变量 / static 变量 和 arrays 都进行了缺省的初始化工作.
        (default  initialization). Local 变量是没有缺省值的, 必须为其明确初始化, 只
        有class 的static变量和instance 变量才有缺省值.

38>   使用基础类型(primitive Types )使代码更快更小
 
         小型基础类型(short / byte / char / boolean)存储于 Stack 上或用于局部
         变量时, 通常被提升为int , 以4bytes 存储.
         使用 primitive Types 时在速度和存储空间上比之类对象或者wrapper对
         象都更好, 但当用到 Java collection classes时必须用对象, 因为群集类都
         只管理 java.lang.object 对象.

39>   不要使用 Enumeration 或 Iterator 来便利 Vector
         Java提供了便利 Vector 元素的几种方法: 
               A>  Iterator (迭代器);               //次次之;
               B>  ListIterator (List 迭代器);      //次次之;
               C>  Enumeration (枚举器);            //次之;
               D>  get() 函数;                     //性能最高;

40>   使用 System.arraycopy() 来复制 arrays
 
         函数调用代价确实高昂, 但也有例外; 比如array 的复制.
         由于 System.arraycopy() 是以本机函数 (native Method)实现的, 因此她的
                 执行速度比之for循环中的赋值操作要快. 同时也由于她是一个本
                 机函数, 所以这个调用动作的执行速度在不同平台上有所不同.

41>   优先使用 Array, 然后才考虑 Vector 和ArrayList
         由于 Vector 和ArrayList 都涉及对象操作, 所以 Array 会比她们两个快很
         多, 其中由于Vector 函数的synchronized , 她会比ArrayList 慢.
         V / A 都支持在需要时自动调整本身体积, 都采用array 作为底部设施, 所
         以当这些classes 调整自身大小的时候,会创建一个新的array, 然后将所有
         的元素从原来的array复制到新的array 中.

42>    尽可能复用 ( reuse) 对象
          对象的复用比之对象的重复创建, 其性能有所优化, 但如果调用函数要
          保存的是 Object reference则 reuse 是不能用的.

44>    以手工方式优化代码
          (javap -c PP > pp.bc    disassemble class File and save it in pp.bc);
          优化技术:
                  A>  删除空白函数 (Empty Method removal);
                  B>  删除无用代码 (Dead code removal );
                  C>  削减强度 (Strength reduction);
                  D>  合并常量 (Constant folding);
                  E>   删除相同的子表达式 (common subexpression elimination);
                  F>   展开循环 (Loop unrolling);
                  G>  简化代数 (Algebraic simplification);
                  H>  移动循环内的不变式 (Loop invariant code motion);

45>    编译为本机代码 (Compile to native code )
          在牺牲Java 的平台可移植性 (platform portability) 的情况下可通过将 Java
          源码编译为本机二进制码 (native binary code)以提高性能. 这种做法并不
          是把Java 源码编译为 bytecode形式,而是直接编译为本机机器指令 ------
          ( native machine instructions);
          这样在运行期将不再为 bytecode --> native code 付出额外代价.
          (static code generation )  静态代码生成方式可以实现上述情况,  只是得放
          弃跨平台性.   如果你的代码只要求在一种机器上运行 ,    如服务器应用
          程序编码 / 嵌入式设备 (embedded device)编码时是不错的选择.
          当代码编译为 native binary code , 没有了JVM 的协助, 此时垃圾回收机制
          怎么工作那?      
          ------  不同厂商对这个问题的答案不尽相同.
              A> 在目标系统上部署一个小型虚拟机, 不需要操心内存管理;
              B> 增加一个delete关键词到她们的Java-like 语言中.不过这样 添加了
                     不属于Java语言规范的东西,无法移植到兼容实现品上;
              C> 在维持Java 平台移植性的同时, 将程序的某些部分编译为本机
                       二进制代码.
原创粉丝点击