在像java这种编程语言中,循环是控制流的最常用的方法之一,在这篇文章中我不打算讨论循环的一些基本的知识,这已经超出本篇文章的范围并且大家已经对此非常的了解了。
在这篇文章中,我将列出在日常中用到的循环的不同的方式并且使用相同的集合比较他们的性能
不同的循环
我将列出我知道的四中不同的方式,如果你知道其他的方式,请通过评论得方式告诉我
for each 语句
这个技术是在java 5之后使用的
private static List<Integer> list = new ArrayList<>();
for(Integer i : list)
{
// do other stuff
}
使用list.size()
private static List<Integer> list = new ArrayList<>();
for(int j = 0; j < list.size() ; j++)
{
//do stuff
}
使用size初始化另一个本地变量
private static List<Integer> list = new ArrayList<>();
int size = list.size();
for(int j = 0; j < size ; j++)
{
//do stuff
}
在循环内部初始化
private static List<Integer> list = new ArrayList<>();
for(int j = list.size(); j > size ; j--)
{
//do stuff
}
比较所有类型的性能
我创建了一个ArrayList并且存入1千万的整数,然后使用者四种方式遍历它,通过这种方式我们可以看到系能的不同
运行环境
java 7
eclipse Juno
package com.howtodoinjava.demo.core;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
public class ForLoopPerformanceTest
{
private static List<Integer> list = new ArrayList<>();
private static long startTime;
private static long endTime;
static
{
for(int i=0; i < 1_00_00_000; i++)
{
list.add(i);
}
}
@SuppressWarnings("unused")
public static void main(String[] args)
{
//Type 1
startTime = Calendar.getInstance().getTimeInMillis();
for(Integer i : list)
{
//
}
endTime = Calendar.getInstance().getTimeInMillis();
System.out.println("For each loop :: " + (endTime - startTime) + " ms");
//Type 2
startTime = Calendar.getInstance().getTimeInMillis();
for(int j = 0; j < list.size() ; j++)
{
//
}
endTime = Calendar.getInstance().getTimeInMillis();
System.out.println("Using collection.size() :: " + (endTime - startTime) + " ms");
//Type 3
startTime = Calendar.getInstance().getTimeInMillis();
int size = list.size();
for(int j = 0; j < size ; j++)
{
//System.out.println(j);
}
endTime = Calendar.getInstance().getTimeInMillis();
System.out.println("Using [int size = list.size(); int j = 0; j < size ; j++] :: " + (endTime - startTime) + " ms");
//Type 4
startTime = Calendar.getInstance().getTimeInMillis();
for(int j = list.size(); j > size ; j--)
{
//System.out.println(j);
}
endTime = Calendar.getInstance().getTimeInMillis();
System.out.println("Using [int j = list.size(); j > size ; j--] :: " + (endTime - startTime) + " ms");
}
}
当执行上边的代码的时候会在控制台输出下边的运行情况
For each loop :: 110 ms
Using collection.size() :: 37 ms
Using [int size = list.size(); int j = 0; j < size ; j++] :: 4 ms
Using [int j = list.size(); j > size ; j--] :: 1 ms
很明显后边的两种方式的性能比较好,而for each的系能和其它三者相比是最昂贵的
性能不同的原因
后边两种的性能差别不大,应该认为是相同的。他们都同样获取集合的大小,然后在循环中使用这个值来检查条件是否成立
第二种在每次调用的时候使用size方法,这是导致性能问题的主要原因。
第一种方式是最耗时的,原因是每个循环内部使用创建的遍历,创建一个遍历和调用iterator.get()和其他三种方法比有很高的性能消耗
原文地址:http://howtodoinjava.com/2013/03/26/performance-comparison-of-different-for-loops-in-java/