java关于for循环的效率优化

摘要:
提取与循环无关的表达式longstratTime=System。纳米时间();对于{i=i*a*b;}longendTime=系统。纳米时间();System.out。打印ln;应将其更改为:longstratTime=System。纳米时间();c=a*b;对于{i=i*c;}longendTime=系统。纳米时间();System.out。打印ln;两者之间的时间消耗比较:未提取的时间消耗:45973050提取的时间:1955代码中的a*b操作独立于循环,因此我们应该将其放在循环之外,以避免重复计算。我们可以看到,优化后的性能提高了几个数量级,这是一个不容忽视的效率问题。
我们知道在实现一个功能的时候是可以使用不同的代码来实现的,那么相应的不同实现方法的性能肯定也是有差别的,所以我们在写一些对性能很敏感的模块的时候,对代码进行优化是很必要的,所以我们说一下for循环(while循环同理)的性能优化。

循环作为三大结构之一,我们在编写代码的时候使用频率非常的高;循环结构的重要性也是不言而喻的,他让我们操作数组、集合和其他一些有规律的事物变得更加的方便,但是如果运用不得当,就会给性能带来很大的负担,所以我们需要掌握一些关键的技巧优化我们的代码:

嵌套循环

long stratTime = System.nanoTime();
for (int i = 0; i < 10000000; i++) {
	for (int j = 0; j < 10; j++) {

	}
}
long endTime = System.nanoTime();
System.out.println("外大内小耗时:"+ (endTime - stratTime));		

应改为:

long stratTime = System.nanoTime();
for (int i = 0; i <10 ; i++) {
	for (int j = 0; j < 10000000; j++) {

	}
}
long endTime = System.nanoTime();
System.out.println("外小内大耗时:"+(endTime - stratTime));

两者耗时对比:

外大内小耗时:200192114  
外小内大耗时:97995997  

我们可以通过结果看出优化后性能提升了一倍,所以嵌套循环应该遵循“外小内大”的原则,这和你拷贝文件的时候复制多个小文件和复制大文件的区别。
其实,这个问题的主要原因是CPU内部的指令执行机制。现在,基本上CPU内部都有分支指令预测,就是当执行(现在大多将这一阶段提前到预取指令时执行)到转移指令时,都会直接从分支目标缓存(BTB)中取出目标指令的地址,然后将要执行的指令提前预取到CPU的指令预取指令队列中。这样,显然大大提高了效率。举个例子,一个10次的一层循环在执行时,除了在第一次和最后一次会预测错误外,其他8次都会预取成功,避免了执行转移指令时重新取出新指令造成的时间浪费。所以,当有两层循环,外层循环数为A,内层为B,A远大于B,那么最终造成的预测错误数为A*2+2,而如果外层数为B,内层数为A,预测错误数为B*2+2,显然后者要节省更多时间,而且这个时间是很可观的。A比B越大,这个时间差越明显。

 

提取与循环无关的表达式

long stratTime = System.nanoTime();
for (int i = 0; i < 10000000; i++) {
	i=i*a*b;
}
long endTime = System.nanoTime();
System.out.println("未提取耗时:"+(endTime - stratTime));

应改为:

long stratTime = System.nanoTime();
c = a*b;
for (int i = 0; i < 10000000; i++) {
	i=i*c;
}
long endTime = System.nanoTime();
System.out.println("已提取耗时:"+(endTime - stratTime));

两者耗时对比:

未提取耗时:45973050  
已提取耗时:1955 

代码中的a*b运算和循环是无关的,所以我们应该把他放到循环的外面,避免重复计算,我们可以看到优化后的性能提升了好几个量级,这可是不容忽视的效率问题。

消除循环终止判断时的方法调用

long stratTime = System.nanoTime();
for (int i = 0; i < list.size(); i++) {

}
long endTime = System.nanoTime();
System.out.println("未优化list耗时:"+(endTime - stratTime));

应改为:

long stratTime = System.nanoTime();
int size = list.size();
for (int i = 0; i < size; i++) {

}
long endTime = System.nanoTime();
System.out.println("优化list耗时:"+(endTime - stratTime));

两者耗时对比:

未优化list耗时:27375  
优化list耗时:2444 

list.size()每次循环都会被执行一次,这无疑会影响程序的性能,所以应该将其放到循环外面,用一个变量来代替,优化前后的对比也很明显。

异常捕获

long stratTime = System.nanoTime();
for (int i = 0; i < 10000000; i++) {
	try {
	} catch (Exception e) {
	}
}
long endTime = System.nanoTime();
System.out.println("在内部捕获异常耗时:"+(endTime - stratTime));

应改为:

long stratTime = System.nanoTime();
try {
     for (int i = 0; i < 10000000; i++) {
     }
} catch (Exception e) {

}
long endTime = System.nanoTime();
System.out.println("在外部捕获异常耗时:"+(endTime - stratTime));

两者耗时对比:

在内部捕获异常耗时:12150142  
在外部捕获异常耗时:1955  

捕获异常是很耗资源的,所以不要把try catch放到循环内部,优化后同样有好几个数量级的提升。

性能优化的内容有很多,代码优化只是其中一小部分,我们在日常开发中应养成良好的编码习惯。希望上面的问答对大家有所帮助!

本人转自:https://www.cnblogs.com/lei-z/p/14086042.html

免责声明:文章转载自《java关于for循环的效率优化》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇数据层交换和高性能并发处理(开源ETL大数据治理工具--KETTLE使用及二次开发 )ArcGIS Server常见问题之二下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

sql记录查询重复注意事项(经验提升),in的用法和效率

sql查询重复记录,使用: select * from dimappnamenew as appn where id in (   select id   from dimappnamenew group by packagename,storename,app_name having count(*)>1 )  id是表的主键,三个属性映射后可以...

Notepad++常用命令——大大提升编码效率

Notepad++常用命令: 1.      Ctrl-D 复制当前行 2.      Ctrl-L 删除当前行 3.      Ctrl-T 将当前行与前一行互换 4.      Ctrl-Shift-Down下移当前行 5.      Ctrl-G 跳转 6.      Ctrl+F 键查找对话框启动 7.      Ctrl+F3 选定查找下一个...

提高程序运行效率的10个简单方法(转)

对于每一个程序员来说,程序的运行效率都是一个值得重视,并为之付出努力的问题。但是程序性能的优化也是一门复杂的学问,需要很多的知识,然而并不是每个程序员都具备这样的知识,而且论述如何优化程序提高程序运行效率的书籍也很少。但是这并不等于我们可以忽略程序的运行效率,下面就介绍一下本人积累的一些简单实用的提高程序运行效率的方法,希望对大家有所帮助。 注:以C/C+...

sqlserver2008r2 版本数据库迁移到2019版本导致查询效率慢的解决方法

1、在sqlserver2008 版本的数据库引擎创建数据库后,迁移到sqlserver2019版本,存储过程查询效率变慢了。 2、主要原因:使用sqlserver2019版本的数据库软件创建,默认是不往低版本的数据库软件兼容。 3、处理版本,右击数据库-》属性-》选项-》兼容级别,选择SQL Server 2008 (100) 即可。    ...

mysql快速保存插入大量数据一些方法总结(转)

本文转自:mysql快速保存插入大量数据一些方法总结 说明: 这几天尝试了使用不同的存储引擎大量插入MySQL表数据,主要试验了MyISAM存储引擎和InnoDB。下面是实验过程: 实现:一、InnoDB存储引擎。创建数据库和表  代码如下 1 > CREATE DATABASE ecommerce; > CREATE TABLE e...

(转)sql union和union all的用法及效率

1 熟悉union的相关操作 UNION指令的目的是将两个SQL语句的结果合并起来。从这个角度来看, 我们会产生这样的感觉,UNION跟JOIN似乎有些许类似,因为这两个指令都可以由多个表格中撷取资料。 UNION的一个限制是两个SQL语句所产生的栏位需要是同样的资料种类。 另外,当我们用 UNION这个指令时,我们只会看到不同的资料值 (类似 SELEC...