- 浏览: 238406 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
xchd:
分别在什么时候(情况下)用ThreadFactory、Exec ...
Executor线程池实例 -
mikey_5:
是不是没有写完啊
Executor线程池实例 -
xinyao:
楼主,你好,请问能给我发个源码吗,我要在一个页面能实时看到下载 ...
Android学习系列(19)--App离线下载 -
sdtzkj:
...
jasperReport 帮助文档 api -
shero_ys:
public class VrowsePicActivity ...
android handler 实现三步曲
java 优化
Java优化策略(一):底层优化
By 冲出宇宙 From 傲尔科技(www.hour41.com)
时间:2006-11-17
注:转载请注明作者和单位。
Java语言标准从1996年发布第一版,到2000年发布第二版,再到2004年发布第三版,java语言已经经过了3次大的扩充和改进。功能是越来越多,操作是越来越复杂。显然,性能问题也就越来越突出。本文将力图从java本身分析优化java代码的各种可能。文章的数据未经特别说明,均来自于jdk5.0版本。
1 Java基本数据类型时间分析
因为单独测试一个基本类型的变量很不精确,无论你怎么测,误差都很大。所以,我们只能大致的给出速度上的差别。
变量的访问速度和访问的类型是有很大关系的,一般我们直接使用2个变量的操作时间来衡量变量的访问速度。显然,byte + byte的速度和int + int的速度肯定是不同的。我们对以下几类基本操作进行了速度测试:加减(+,-)、乘(*)、除(/)、移位(>>,<<,>>>,<<<)和布尔运算(|,&,^)。为了保证数据的有效性,测试得到了3份结果,取平均值,得到下面的各个基本数据类型的大致时间花销比例如下表(以下均以此作为参考对象,一个时间单位在我的机器上大约是600ps,即0.6ns,也就是6e-10秒):
加减
乘
除
移位
布尔运算
byte
1.5
6
50
1.5
1
short
1.2
5.5
50
1.2
1
int
1
5
48
1
1
long
5
10
140
8.5
2
float
15
600
350
-
-
double
15
600
350
-
-
从表中我们可以看出:
1. int的运算速度最快,short次之,byte再次之,long再次之。float和double运算速度最慢。
2. 除法比乘法慢的太多,基本上除法是乘法的9倍时间。当然,除了浮点型外。根据intel cpu的参考数据,乘法计算时间是移位运算的4-5倍是比较正常的。
3. long类型的计算很慢,建议一般少使用它。
4. double运算速度和float相当;
5. 浮点的乘法比除法要慢。但是,这个结果并不能真正说明问题。这个结果只是一个一般性的,在特殊情况下,乘法还是比除法快,比如:floatA * floatB 仍然是比floatA / (1/floatB)快。从实际的数据结果来讲,乘法的时候,乘数越小速度越快,特别是在乘数比3小的时候,乘法时耗接近20,大于4的时候,几乎都是600的时耗。除法恰好相反,除数大于1的时候,时耗一般都是350,可是,当除数小于1的时候,时耗就变成了700了。
对于大家关心的移位和乘除2的问题,jdk5.0已经做了部分处理。即“var *=2”和“var <<=1”耗费一样。但是,除法并没有进行这类处理,即“var /= 2”耗费和基本的除法一样。
2 Java类和接口调用时间分析
2.1 类的创建
虽然面向对象思想已经深入人心,但他在带来快捷方面的编程风格的时候,也带来了低下的效率。在Java中,反应最快的是Object类(这也是显然的),建立一个新的Object类时耗仅仅为20单位。而一个空类(即没有声明任何Methods和Fields)的建立时间则增加到了惊人的400单位。如果再给类增加一些字段的话,时间耗费并没有特别大的增加,每增加一个int类型字段大概增加30个单位。
仅仅就创建时间来说,内嵌的类型都有不错的表现。比如,创建一个int数组(仅仅包含一个元素)的时间只比创建一个Object对象的时间多一倍。当然,如果你创建的数组对象包含1000个元素的话,其创建时间显然还会加上内存管理的时间了,它的时间大概是1万个时间单位。请注意,我们这里讨论的时间单位其实十分小,1万个时间单位也仅仅只是有0.006毫秒(0.000006秒)。创建一个byte、short、int、long、float和double数组对象的时间消耗几乎是一样的。
2.2 方法的调用
Java在这个方面有一点做得很好,就是调用一个只有很少量代码的方法的时耗和直接把这段代码写到本地的时耗相差很小。当然不包括需要分配很多本地变量的情况。
调用本类(this指针)的方法是最快的,时间在1-2个单位。调用其它类的静态方法也很快,速度和调用本来方法差不多。调用其它类的非静态方法速度就慢一些,在1.5-2.5个时间单位之间。
调用继承接口的方法是十分缓慢的,是调用普通方法的3倍。但是,如果在实现接口的时候加上final关键字的话,调用这个方法的时耗就和普通方法差不多了。
最慢的是已经同步化了的方法。即加上了synchronized关键字的方法。调用它的时耗比普通方法高出了近20倍。如果不是万不得已,不要把synchronized加到方法上面,实在不行的话,你可以把它加到代码块上去,这种加法比直接加到方法上面快一点。
注意,因为方法大部分时候都是完成很多事情的,所以,十分注意调用方法的开销是没有必要的,因为这个时间和方法执行需要的时间比较起来只是毛毛雨。
3 Java基本操作时间耗费
3.1 基本语句
for循环一次的时间耗费在5个单位左右,本地int变量赋值一次的时间耗费在1-2个单位。下表列出了各种操作的时间耗费:
操作
时间耗费
int var = var
1.5
int array[0] = array[0]
4
for
6
throw --- catch
5000
3.2 Cast的时间耗费
下表是各种类型之间转化的时间耗费:
转化形式
时耗
SubClass = (SubClass) SuperClass
4
Interface = (Interface) Class
4
int à byte, intà char, intà short, intà long
1
intàfloat, intàdouble
3
intß long
10-15
intß float, intß double
15-20
longß float, longß double
30-40
4 基本优化策略
基本优化策略的天字第一条就是:不要优化!优化代码会使得代码难以理解,代码之间的逻辑结构会变得十分混乱。所以,优化大师们的建议就是:不到万不得已,千万不要优化你的代码。可惜的是,在搜索引擎方面,处处都是效率的考虑。
基本的优化策略有以下几条:
1. 选定优化目标。优化不是对所有代码进行优化,这是因为优化代码的代价很高。优化只需要针对少部分代码进行。在这里,90/10或者80/20规则发挥着重要作用。找到代码中最影响速度的地方,然后把块骨头啃下来!
2. 操作符简约。换一个操作符代替原有操作符。这里说的最主要例子就是:用“>>=n”替换“/= 2^n”和“<<=n”替换“*=2^n”。Java用不着第2种替换。
3. 共同表达是提取。提取2个表达式中相同的部分,避免同一个式子重复计算。比如:double x = d * a*b;
double y = e * a*b;
就可以化为:
c = a*b;
x = d*c;
y = e*c;
4. 代码移动。把那些在运算中不改变值的变量放到前面先计算好。比如:
for(int i=0;i
{
x[i] *= Math.PI * Math.cos(y);
}
就可以修改为:
double d = Math.PI * Math.cos(y);
for(int i=0;i
{
x[i] *= d;
}
5. 分解循环。循环可以简化代码,同时,他们也增加了额外的循环开销。可以通过减少循环次数或者取消循环来获得更好的性能。比如:
for(int i=0;i<1000000;i++)
{
x[i] = i;
}
就能够变成:
for(int i=0;i<1000000;i+=2)
{
x[i] = i;
x[i+1] = i+1;
}
6. 循环的替换。一般认为把“for(i=0;i”替换成“for(i=n;--i>=0;)”会有更好的效果。不过,我们的测试结果显示,在JDK5.0的环境下面,这种方式几乎没有任何速度提升。
7. 取消for判断。把“for(i=0;i”转化为“for(i=0;;i++)”,如果里面的代码能够在i>=n的时候出错的话,这段循环就能够自己结束(通过Exception)。可是,测试的结果说明,只有在n特别大的时候,比如1000万,这种方式才能提高速度。其依据是:exception特别耗时。
5 Java的优化建议
虽然很多基本的优化策略对JDK5.0并不起作用,我们还是可以根据以上对JDK5.0性能的分析得到一些明显的优化建议的。列举如下:
1. 使用平行数组代替值类。平行数组的概念见
http://lotusroots.bokee.com/5787315.html。值类的意思是说没有方法的类或者Beans类。
2. 如果可以,不要使用接口;万一必须使用接口,请在继承的类的方法上面加上final关键字。
3. 方法尽量加上static关键字。这样不仅仅是为了调用速度,更能减少空间占用。
4. 使用已经存在的对象来生成新对象。不要用手动初始化的方式生成对象的拷贝。
5. 避免生成新的对象。
6. 严格控制synchronized关键字的使用。
7. 利用System.arraycopy拷贝数组。
8. 使用int,使用int/long代替浮点,用乘不用除,多用布尔运算。
最后的建议是:使用最新的JDK!! 为什么这么说呢?因为我们测试JDK6.0beta2的速度比JDK5.0快了近15%,这是对基本数据类型进行的运算的测试结果。
Java优化策略(一):底层优化
By 冲出宇宙 From 傲尔科技(www.hour41.com)
时间:2006-11-17
注:转载请注明作者和单位。
Java语言标准从1996年发布第一版,到2000年发布第二版,再到2004年发布第三版,java语言已经经过了3次大的扩充和改进。功能是越来越多,操作是越来越复杂。显然,性能问题也就越来越突出。本文将力图从java本身分析优化java代码的各种可能。文章的数据未经特别说明,均来自于jdk5.0版本。
1 Java基本数据类型时间分析
因为单独测试一个基本类型的变量很不精确,无论你怎么测,误差都很大。所以,我们只能大致的给出速度上的差别。
变量的访问速度和访问的类型是有很大关系的,一般我们直接使用2个变量的操作时间来衡量变量的访问速度。显然,byte + byte的速度和int + int的速度肯定是不同的。我们对以下几类基本操作进行了速度测试:加减(+,-)、乘(*)、除(/)、移位(>>,<<,>>>,<<<)和布尔运算(|,&,^)。为了保证数据的有效性,测试得到了3份结果,取平均值,得到下面的各个基本数据类型的大致时间花销比例如下表(以下均以此作为参考对象,一个时间单位在我的机器上大约是600ps,即0.6ns,也就是6e-10秒):
加减
乘
除
移位
布尔运算
byte
1.5
6
50
1.5
1
short
1.2
5.5
50
1.2
1
int
1
5
48
1
1
long
5
10
140
8.5
2
float
15
600
350
-
-
double
15
600
350
-
-
从表中我们可以看出:
1. int的运算速度最快,short次之,byte再次之,long再次之。float和double运算速度最慢。
2. 除法比乘法慢的太多,基本上除法是乘法的9倍时间。当然,除了浮点型外。根据intel cpu的参考数据,乘法计算时间是移位运算的4-5倍是比较正常的。
3. long类型的计算很慢,建议一般少使用它。
4. double运算速度和float相当;
5. 浮点的乘法比除法要慢。但是,这个结果并不能真正说明问题。这个结果只是一个一般性的,在特殊情况下,乘法还是比除法快,比如:floatA * floatB 仍然是比floatA / (1/floatB)快。从实际的数据结果来讲,乘法的时候,乘数越小速度越快,特别是在乘数比3小的时候,乘法时耗接近20,大于4的时候,几乎都是600的时耗。除法恰好相反,除数大于1的时候,时耗一般都是350,可是,当除数小于1的时候,时耗就变成了700了。
对于大家关心的移位和乘除2的问题,jdk5.0已经做了部分处理。即“var *=2”和“var <<=1”耗费一样。但是,除法并没有进行这类处理,即“var /= 2”耗费和基本的除法一样。
2 Java类和接口调用时间分析
2.1 类的创建
虽然面向对象思想已经深入人心,但他在带来快捷方面的编程风格的时候,也带来了低下的效率。在Java中,反应最快的是Object类(这也是显然的),建立一个新的Object类时耗仅仅为20单位。而一个空类(即没有声明任何Methods和Fields)的建立时间则增加到了惊人的400单位。如果再给类增加一些字段的话,时间耗费并没有特别大的增加,每增加一个int类型字段大概增加30个单位。
仅仅就创建时间来说,内嵌的类型都有不错的表现。比如,创建一个int数组(仅仅包含一个元素)的时间只比创建一个Object对象的时间多一倍。当然,如果你创建的数组对象包含1000个元素的话,其创建时间显然还会加上内存管理的时间了,它的时间大概是1万个时间单位。请注意,我们这里讨论的时间单位其实十分小,1万个时间单位也仅仅只是有0.006毫秒(0.000006秒)。创建一个byte、short、int、long、float和double数组对象的时间消耗几乎是一样的。
2.2 方法的调用
Java在这个方面有一点做得很好,就是调用一个只有很少量代码的方法的时耗和直接把这段代码写到本地的时耗相差很小。当然不包括需要分配很多本地变量的情况。
调用本类(this指针)的方法是最快的,时间在1-2个单位。调用其它类的静态方法也很快,速度和调用本来方法差不多。调用其它类的非静态方法速度就慢一些,在1.5-2.5个时间单位之间。
调用继承接口的方法是十分缓慢的,是调用普通方法的3倍。但是,如果在实现接口的时候加上final关键字的话,调用这个方法的时耗就和普通方法差不多了。
最慢的是已经同步化了的方法。即加上了synchronized关键字的方法。调用它的时耗比普通方法高出了近20倍。如果不是万不得已,不要把synchronized加到方法上面,实在不行的话,你可以把它加到代码块上去,这种加法比直接加到方法上面快一点。
注意,因为方法大部分时候都是完成很多事情的,所以,十分注意调用方法的开销是没有必要的,因为这个时间和方法执行需要的时间比较起来只是毛毛雨。
3 Java基本操作时间耗费
3.1 基本语句
for循环一次的时间耗费在5个单位左右,本地int变量赋值一次的时间耗费在1-2个单位。下表列出了各种操作的时间耗费:
操作
时间耗费
int var = var
1.5
int array[0] = array[0]
4
for
6
throw --- catch
5000
3.2 Cast的时间耗费
下表是各种类型之间转化的时间耗费:
转化形式
时耗
SubClass = (SubClass) SuperClass
4
Interface = (Interface) Class
4
int à byte, intà char, intà short, intà long
1
intàfloat, intàdouble
3
intß long
10-15
intß float, intß double
15-20
longß float, longß double
30-40
4 基本优化策略
基本优化策略的天字第一条就是:不要优化!优化代码会使得代码难以理解,代码之间的逻辑结构会变得十分混乱。所以,优化大师们的建议就是:不到万不得已,千万不要优化你的代码。可惜的是,在搜索引擎方面,处处都是效率的考虑。
基本的优化策略有以下几条:
1. 选定优化目标。优化不是对所有代码进行优化,这是因为优化代码的代价很高。优化只需要针对少部分代码进行。在这里,90/10或者80/20规则发挥着重要作用。找到代码中最影响速度的地方,然后把块骨头啃下来!
2. 操作符简约。换一个操作符代替原有操作符。这里说的最主要例子就是:用“>>=n”替换“/= 2^n”和“<<=n”替换“*=2^n”。Java用不着第2种替换。
3. 共同表达是提取。提取2个表达式中相同的部分,避免同一个式子重复计算。比如:double x = d * a*b;
double y = e * a*b;
就可以化为:
c = a*b;
x = d*c;
y = e*c;
4. 代码移动。把那些在运算中不改变值的变量放到前面先计算好。比如:
for(int i=0;i
{
x[i] *= Math.PI * Math.cos(y);
}
就可以修改为:
double d = Math.PI * Math.cos(y);
for(int i=0;i
{
x[i] *= d;
}
5. 分解循环。循环可以简化代码,同时,他们也增加了额外的循环开销。可以通过减少循环次数或者取消循环来获得更好的性能。比如:
for(int i=0;i<1000000;i++)
{
x[i] = i;
}
就能够变成:
for(int i=0;i<1000000;i+=2)
{
x[i] = i;
x[i+1] = i+1;
}
6. 循环的替换。一般认为把“for(i=0;i”替换成“for(i=n;--i>=0;)”会有更好的效果。不过,我们的测试结果显示,在JDK5.0的环境下面,这种方式几乎没有任何速度提升。
7. 取消for判断。把“for(i=0;i”转化为“for(i=0;;i++)”,如果里面的代码能够在i>=n的时候出错的话,这段循环就能够自己结束(通过Exception)。可是,测试的结果说明,只有在n特别大的时候,比如1000万,这种方式才能提高速度。其依据是:exception特别耗时。
5 Java的优化建议
虽然很多基本的优化策略对JDK5.0并不起作用,我们还是可以根据以上对JDK5.0性能的分析得到一些明显的优化建议的。列举如下:
1. 使用平行数组代替值类。平行数组的概念见
http://lotusroots.bokee.com/5787315.html。值类的意思是说没有方法的类或者Beans类。
2. 如果可以,不要使用接口;万一必须使用接口,请在继承的类的方法上面加上final关键字。
3. 方法尽量加上static关键字。这样不仅仅是为了调用速度,更能减少空间占用。
4. 使用已经存在的对象来生成新对象。不要用手动初始化的方式生成对象的拷贝。
5. 避免生成新的对象。
6. 严格控制synchronized关键字的使用。
7. 利用System.arraycopy拷贝数组。
8. 使用int,使用int/long代替浮点,用乘不用除,多用布尔运算。
最后的建议是:使用最新的JDK!! 为什么这么说呢?因为我们测试JDK6.0beta2的速度比JDK5.0快了近15%,这是对基本数据类型进行的运算的测试结果。
发表评论
-
Android JNI简单实例(android 调用C/C++代码)
2011-05-25 11:19 6261Android的jni实例 android 的应用程序( ... -
设计模式之Factory
2011-02-12 10:14 810工厂模式定义:提供创建对象的接口. 为何使用?工厂模式是我们 ... -
svn配置方法
2011-01-06 15:37 882Install Subclipse in Eclipse 3. ... -
Java面向对象
2010-12-27 13:15 808编程模型 所有计算 ... -
用java原生api写解压缩
2010-12-06 09:27 787package com.unis.io; impo ... -
java 多线程详解
2010-11-26 15:42 1129目录: Java线程:概念与原理... 3 Java ... -
Java 多线程总结
2010-11-11 11:04 949最近想将java基础的一些 ... -
项目部署
2010-06-30 09:30 772是 -
java 读取文件
2010-06-17 13:53 1340java 读取 txt文件 ... -
生成hibernate配置文件
2010-06-13 15:32 618项目添加hibernate配置文件: 1. 首先 ... -
使用JDOM来生成XML文档
2010-05-17 17:11 1538下面介绍使用Eclipse来加载JDOM的jar包,同时利用J ... -
日期类型之间转换
2010-05-06 12:08 957public static Timestamp parseT ... -
JSTL详解--EL表达式
2010-03-25 11:03 1118在 JSP 页面中,使用标签库代替传统的 Java 片段语 ... -
JSTL 学习、应用记录
2010-03-24 17:25 1001JSTL 学习、应用记录 原来一直没有看过,我说过我是新手, ... -
Struts2+Spring整合
2010-03-08 16:01 1224Struts2和Spring整合,创建一个OA工程 1、整合s ... -
S2SH整合配置
2010-03-08 10:29 1266配置方法1: ********************* ... -
hibernate中lazy的使用
2010-03-08 10:25 808hibernate中lazy的使用 lazy,延迟 ... -
Java static final
2010-03-05 13:54 1676Java关键字final、static使用总结 一、 ... -
Java 反射机制
2010-03-05 09:56 799JAVA反射机制 JAV ... -
Java 工厂模式
2010-03-02 10:59 8116 推荐 一、引子话说十年 ...
相关推荐
Java优化编程是提升Java应用程序性能的关键技术,涵盖了多个方面的知识,包括代码优化、内存管理、垃圾回收、并发处理以及JVM参数调优等。以下是对这些主题的详细讲解: 1. **代码优化**:编写高效的Java代码是优化...
一本经典的关于java优化编程的书。通过丰富、完整、富有代表性的实例,展示了如何提升Java应用性能,并且给出了优化前与优化后的Java应用程序的性能差别,以实际的实例与数字告诉你,为什么不可以这么做,应该怎么做...
本文将深入探讨Java优化的多个方面,帮助开发者掌握优化技巧,提升代码质量。 首先,我们要了解JVM(Java虚拟机)的工作原理,因为它是Java代码执行的基础。理解JVM内存模型,包括堆内存、栈内存、方法区、元空间等...
《Java优化手册》深入浅出地探讨了Java编程中的性能优化策略,主要涵盖了底层篇和通用篇的内容。本文将详细解析这些知识点。 1. 底层篇 1.1. 基本数据类型时间分析 Java中的基本数据类型运算速度有显著差异。int...
**Java优化编程PPT讲义概述** 这是一份专门针对Java优化编程的内部培训资料,旨在帮助中级及以上水平的开发者提升代码性能,实现更高效的应用程序。这份讲义结合了理论与实践,深入探讨了Java语言在实际开发中的...
在这个压缩包文件"Java优化大师.rar"中,包含了一个名为"Java优化大师1.0.exe"的可执行文件,这可能是该工具的安装程序。 Java优化主要包括以下几个关键方面: 1. **代码优化**:编写高效的代码是优化的第一步。...
在《JAVA优化编程详解》这本书中,作者深入探讨了如何将Java编程技能提升到一个全新的层次,特别是聚焦于性能优化这一关键领域。Java优化不仅仅是关于提高代码运行速度,更是关于资源的有效利用,确保应用程序在复杂...
对java编程的优化作了比较详尽的讲解,包括内存怎么优化,程序的优化,ejb、jms的优化
【Java优化版万年历】是一个Java编程项目,旨在提供一个功能完备的日历应用程序,能够显示从公元1年至公元9999年的日期信息。这个优化版本是在原版基础上进行了性能提升和用户体验改进,适用于Java爱好者学习和研究...
JAVA优化编程,这是一本讲解关于java编程方面应该如何编码才能是你的java程序取得更高的效率,也许你说没必要,当实际上对程序进行优化是相当重要和必要的。如果你在学习java或者已经学习了java的基本语法,那么我...
JAVA优化编程,这是一本讲解关于java编程方面应该如何编码才能是你的java程序取得更高的效率,也许你说没必要,当实际上对程序进行优化是相当重要和必要的。如果你在学习java或者已经学习了java的基本语法,那么我...
### Java优化技术详解 #### 一、引言 在当今高度竞争的应用开发领域,提高Java应用的性能成为了软件工程师的一项重要任务。Java作为一种跨平台的编程语言,虽然提供了丰富的特性和便利性,但在某些场景下可能会...
在Java优化编程中,我们关注的是如何提升程序的性能、减少资源消耗以及提高代码的可维护性。这是一项至关重要的任务,特别是在处理大数据、高并发或者长时间运行的服务时。以下是一些关键的知识点: 1. **JVM优化**...
"JAVA优化编程_程序设计"的主题着重于如何提高Java应用程序的性能,降低资源消耗,提升用户体验。这涉及到一系列的专业知识和技术,包括但不限于内存管理、并发处理、代码优化策略以及垃圾回收机制等。 1. **内存...
Java优化是提升应用程序性能的关键步骤,尤其是在处理大数据、并发或者长时间运行的服务中。"java优化代码1.0版本.7z" 压缩包很可能包含了一组针对Java编程语言的性能优化实践和示例代码。这个压缩包的名称表明它是...
《JAVA优化编程》一书深入探讨了JAVA编程中的性能优化技术,旨在帮助开发者提升应用程序的运行效率和系统资源利用率。在JAVA开发过程中,优化是必不可少的一环,它能确保程序在面对大规模数据处理、高并发场景时仍能...
标题中的"hp.rar_JAVA 优化算法_genetic algorithms_优化算法_遗传算法 _遗传算法 java"表明这是一个关于使用Java实现遗传算法的资源包,它可能包含源代码、示例和相关文档,帮助开发者理解和应用遗传算法。...
《Java优化编程》是一本深入探讨Java技术领域性能优化的专业书籍,主要涵盖了Java语言、JSP、Servlet以及JDBC这四个关键领域的优化策略和技术。在Java编程中,优化是提高程序运行效率、减少资源消耗、提升用户体验的...
在深入探讨《开发资料下载JAVA优化编程(上)》这篇文章的具体内容之前,我们首先要明确几个关键点。首先,这篇文章的标题已经直接告诉我们,本文将聚焦于Java编程语言的性能优化问题。其次,由于描述部分提供的是一...
一本不错的书,会对你的JAVA编程水平有很大提高