有助于改善性能的技巧

1. 慎用异常

  在Java软件开发中,经常会使用try-catch进行错误捕获,但是,try-catch语句对系统性能而言是非常糟糕的。因此,应尽量避免将其应用在循环当中。

2. 使用局部变量

  调用方法时传递的参数以及在调用中创建的临时变量都保存在栈(Stack)中,速度较快。其它变量,如静态变量、实例变量等,都在堆(Heap)中创建,速度较慢。

3. 位运算代替乘除法

  在所有的运算中,位运算是最为高效的。因此,可以尝试使用位运算代替部分算术运算,来提高系统的运算速度。最典型的就是对于整数的乘除法运算优化。

4. 替换switch

  关键字switch语句用于多条件判断,switch语句的功能类似于if-else语句,两者的性能也差不多。因此,不能说switch语句会降低系统的性能。但是,在绝大部分情况下,switch语句还是有性能提升空间的。

  来看下面的例子:

        int re = 0;
        for(int i=0;i<10000000;i++){
            re = switchInt(i);
        }
        protected int switchInt(int z){
            int i = z%10 + 1;
            switch(i){
                case 1:return 3;
                case 2:return 6;
                case 3:return 7;
                case 4:return 8;
                case 5:return 10;
                case 6:return 16;
                case 7:return 18;
                case 8:return 44;
                default:return -1;
            }
        }

  上例中,就分支逻辑而言,这种switch模式的性能并不差。但是如果换一种全新的思路替代switch,实现相同的程序功能,那么性能就能有很大的提升空间。以下代码实现了与上例switch语句相同的功能:

        int re = 0;
        int[] sw = new int[]{0, 3, 6, 7, 8, 10, 16, 18, 44}; //替代switch逻辑
        for(int i=0;i<10000000;i++){
            re = arrayInt(sw, i);
        }
        protected int arrayInt(int[] sw, int z){
            int i = z%10 + 1;
            if(i<1||i>8)    //模拟switch的default
                return -1;
            else
                return sw[i];
        }

  以上代码采用全新的思路,使用一个连续的数组代替了switch语句。因为对数组的随机访问时非常快的,至少好于switch的分值判断,因此它的速度一定会快于原来的实现。通过实验,使用switch的语句相对耗时80ms,而使用数组的实现只相对耗时62ms。

5. 一维数组代替二维数组

  由于数组的随机访问性能非常好,许多JDK类库,如Arraylist、Vector等都使用了数组作为其底层实现。但是,作为软件开发人员也必须知道,一维数组和二维数组的访问速度是不一样的。一维数组的访问速度要优于二维数组。因此,在性能敏感的系统中要使用二维数组的,可以尝试通过可靠的算法,将二维数组转为一维数组再进行处理,以提高系统的响应速度。

6. 提取表达式

  在软件开发过程中,程序员很容易有意无意地让代码做一些“重复劳动”,在大部分情况下,由于计算机的高速运行,这些“重复劳动”并不会对性能构成太大的威胁,但若希望将系统性能发挥到极致,提取这些“重复劳动”相当有意义。尽可能让程序少做重复计算,尤其要关注在循环体内的代码,从循环体内提取重复的代码可以有效地提升系统性能。

7. 展开循环

  与前面所介绍的优化技巧略有不同,展开循环是一种在极端情况下使用的优化手段,因为展开循环很可能会影响代码的可读性和可维护性,而这两者对软件系统来说也是极为重要的。但是,当性能问题成为系统的主要矛盾时,展开循环绝对是一种值得尝试的技术。

一个普通的循环代码如下所示:

     int[] array = new int[9999999];
        for(int i=0;i<9999999;i++){
            array[i] = i;
        }

展开循环后,类似以下格式:

        int[] array = new int[9999999];
        for(int i=0;i<9999999;i += 3){
            array[i] = i;
            array[i+1] = i+1;
            array[i+2] = i+2;
        }

  以上两段代码功能完全相同,但第二段代码进行了循环展开的优化,在一个循环体内处理了原代码段中的3个循环逻辑。运行以上两段代码,第一段代码相对耗时94ms,第二段代码相对耗时31ms,可见展开循环后,减少循环次数,对提升系统性能很有帮助。

8. 布尔运算代替位运算

  虽然位运算的速度远远高于算术运算,但是在条件判断时,使用位运算替代布尔运算却是非常错误的选择。因为在条件判断时,Java会对布尔运算做相当充分的优化。在布尔表达式的计算中,只要表达式的值可以确定,就会立即返回,而跳过剩余子表达式的计算。若使用位运算(按位与、按位或)代替逻辑与和逻辑或,虽然位运算本身性能没有问题,但是位运算总是要将所有的子表达式全部计算完成后,再给出最终结果。因此,从这个角度说,使用位运算替代布尔运算会使系统进行很多无用计算。

9. 使用arraycopy()

  数组复制是一项使用频率很高的功能,JDK中提供了一个高效的API来实现它:

public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);

  System.arraycopy()函数是native函数,通常native函数的性能要优于普通函数,仅出于性能考虑,在软件开发时,应尽可能调用native函数。

10. 使用Buffer进行I/O操作

  除NIO外,使用java进行I/O操作有两种基本方式:

  1. 使用基于InputStream和OutputStream的方式
  2. 使用Writer和Reader

  无论使用哪种方式进行文件的I/O,如果能合理地使用缓冲,就能有效地提高I/O的性能。

11. 使用clone()代替new

  在Java中新建对象实例最常用的方法是使用new关键字。JDK对new关键字的支持非常好,使用new关键字创建轻量级对象时,速度非常快。但是,对于重量级对象,由于对象在构造函数中可能会进行一些复杂而且耗时的操作,因此,构造函数的执行时间可能会比较长。这就导致了创建对象的耗时很长,同时也使得系统无法在短期内获得大量的实例。为了解决这个问题,可以使用Object.clone()方法。

  Object.clone()方法可以绕过对象构造函数,快速复制一个对象实例。由于不需要调用对象构造函数,因此,clone()方法不会受到构造函数性能的影响,能够快速生成一个实例。但是,在默认的情况下,clone()方法生成的实例只是原对象的浅拷贝。如果需要深拷贝,则需要重新实现clone()方法。

12. 静态方法替代实例方法

  使用关键字static声明的方法为静态方法。在Java中,由于实例方法需要维护一张类似虚函数表的结构,以实现对多态的支持。与静态方法相比,实例方法的调用需要更多的资源。因此,对于一些常用的工具类方法,没有对其进行重载的必要,那么就可以将它们声明为static,便可以加速方法的调用。

时间: 2024-11-03 21:41:45

有助于改善性能的技巧的相关文章

Asp.net性能优化技巧

[摘 要] 我只是提供我几个我认为有助于提高写高性能的asp.net应用程序的技巧,本文提到的提高asp.net性能的技巧只是一个起步,更多的信息请参考<Improving ASP.NET Performance>一书. 1. 数据库访问性能优化 数据库的连接和关闭 访问数据库资源需要创建连接.打开连接和关闭连接几个操作.这些过程需要多次与数据库交换信息以通过身份验证,比较耗费服务器资源.ASP.NET中提供了连接池(Connection Pool)改善打开和关闭数据库对性能的影响.系统将用户

心得总结:Java性能优化技巧集锦

一.通用篇 “通用篇”讨论的问题适合于大多数Java应用. 1.1 不用new关键词创建类的实例 用new关键词创建类的实例时,构造函数链中的所有构造函数都会被自动调用.但如果一个对象实现了Cloneable接口,我们可以调用它的clone()方法.clone()方法不会调用任何类构造函数. 在使用设计模式(Design Pattern)的场合,如果用Factory模式创建对象,则改用clone()方法创建新的对象实例非常简单.例如,下面是Factory模式的一个典型实现: public sta

asp.net提高程序性能的技巧(一)

[摘 要] 我只是提供我几个我认为有助于提高写高性能的asp.net应用程序的技巧,本文提到的提高asp.net性能的技巧只是一个起步,更多的信息请参考<Improving ASP.NET Performance>一书. 1. 数据库访问性能优化 数据库的连接和关闭 访问数据库资源需要创建连接.打开连接和关闭连接几个操作.这些过程需要多次与数据库交换信息以通过身份验证,比较耗费服务器资源.ASP.NET中提供了连接池(Connection Pool)改善打开和关闭数据库对性能的影响.系统将用户

Java 性能优化技巧集锦

摘要: =================================== 可供程序利用的资源(内存.CPU时间.网络带宽等)是有限的,优化的目的就是让程序用尽可能少的资源完成预定的任务.优化通常包含两方面的内容:减小代码的体积,提高代码的运行效率.本文讨论的主要是如何提高代码的效率. =================================== 提纲: =================================== 一.通用篇 1.1 不用new关键词创建类的实例 1.2

java性能优化技巧

一.通用篇 "通用篇"讨论的问题适合于大多数 Java应用. 1.1     new 1.1     new 11..11 不用 nneeww关键词创建类的实例 用new 关键词创建类的实例时,构造函数链中的所有构造函数都会被自动调用.但如 果一个对象实现了Cloneable 接口,我们可以调用它的clone()方法.clone()方法不会调用任 何类构造函数. 在使用设计模式(Design Pattern)的场合,如果用 Factory模式创建对象,则改用clone() 方法创建新的

[转] Python 代码性能优化技巧

选择了脚本语言就要忍受其速度,这句话在某种程度上说明了 python 作为脚本的一个不足之处,那就是执行效率和性能不够理想,特别是在 performance 较差的机器上,因此有必要进行一定的代码优化来提高程序的执行效率.如何进行 Python 性能优化,是本文探讨的主要问题.本文会涉及常见的代码优化方法,性能优化工具的使用以及如何诊断代码的性能瓶颈等内容,希望可以给 Python 开发人员一定的参考. Python 代码优化常见技巧 代码优化能够让程序运行更快,它是在不改变程序运行结果的情况下

Python 代码性能优化技巧(转)

原文:Python 代码性能优化技巧 Python 代码优化常见技巧 代码优化能够让程序运行更快,它是在不改变程序运行结果的情况下使得程序的运行效率更高,根据 80/20 原则,实现程序的重构.优化.扩展以及文档相关的事情通常需要消耗 80% 的工作量.优化通常包含两方面的内容:减小代码的体积,提高代码的运行效率. 改进算法,选择合适的数据结构 一个良好的算法能够对性能起到关键作用,因此性能改进的首要点是对算法的改进.在算法的时间复杂度排序上依次是: O(1) -> O(lg n) -> O(

6个Python性能优化技巧

ython是一门非常酷的语言,因为很少的Python代码可以在短时间内做很多事情,并且,Python很容易就能支持多任务和多重处理. Python的批评者声称Python性能低效.执行缓慢,但实际上并非如此:尝试以下6个小技巧,可以加快Python应用程序. 1.关键代码可以依赖于扩展包 Python使许多编程任务变得简单,但是对于很关键的任务并不总是提供最好的性能.使用C.C++或者机器语言扩展包来执行关键任务能极大改善性能.这些包是依赖于平台的,也就是说,你必须使用特定的.与你使用的平台相关

JavaScript 如何工作:渲染引擎和性能优化技巧

翻译自:How JavaScript works: the rendering engine and tips to optimize its performance 这是探索 JavaScript 及其构建组件专题系列的第 11 篇.在识别和描述核心元素的过程中,我们分享了在构建 SessionStack 时使用的一些经验法则.SessionStack 是一个需要鲁棒且高性能的 JavaScript 应用程序,它帮助用户实时查看和重现它们 Web 应用程序的缺陷. 当构建 Web 应用程序时,