参加效率对比的遍历方法:
- for 循环遍历
- for each( ... in ) 循环遍历
- Array类实例自带的实例方法forEach()
由于for(...in)循环更适用于遍历键而非值,故忽略该方法。
效率验证思路:
对三个状态相同的数组分别通过上面罗列的三种方法进行遍历,对数组对象进行相同的操作,而后通过循环开始时间与结束时间的差值获取三种方法分别花费的时间。将此过程反复20次,最后获得三组时间数据。
为了验证三种方法对不同量级长度数组的执行时长差异,将如上过程对10K、100K、1000K长度数组分别执行一遍。
验证结果数据:
- 对长度10K的数组验证结果:
for 循环遍历结果:7,5,5,5,5,7,5,11,6,5,5,5,6,5,5,6,6,7,5,5for 循环遍历总时长: 116 毫秒for each...in 循环遍历结果:5,5,4,4,4,4,5,6,8,5,5,5,4,4,4,5,6,5,4,7for each...in 循环遍历总时长: 99 毫秒somearray.forEach() 遍历结果:6,5,6,5,6,6,6,11,8,5,6,7,6,5,6,6,6,6,6,6somearray.forEach() 遍历总时长: 124 毫秒
- 对长度为100K的数组验证结果:
for 循环遍历结果:49,49,57,50,56,52,53,50,52,49,55,52,50,69,55,58,52,49,51,50for 循环遍历总时长: 1058 毫秒for each...in 循环遍历结果:45,51,46,42,43,43,42,41,45,42,42,43,42,43,48,46,41,43,40,42for each...in 循环遍历总时长: 870 毫秒somearray.forEach() 遍历结果:59,59,59,61,59,58,57,60,62,59,60,57,57,59,67,64,57,60,57,56somearray.forEach() 遍历总时长: 1187 毫秒
- 对长度为1000K的数组验证结果:
for 循环遍历结果:528,503,503,501,509,512,500,500,496,494,510,550,531,534,502,508,503,501,487,501for 循环遍历总时长: 10173 毫秒for each...in 循环遍历结果:434,454,422,427,432,415,426,427,427,431,440,553,426,433,425,431,422,428,427,433for each...in 循环遍历总时长: 8713 毫秒somearray.forEach() 遍历结果:582,615,578,601,597,587,589,583,585,587,649,570,597,586,589,587,594,582,577,586somearray.forEach() 遍历总时长: 11821 毫秒
由以上结果可以看出,Array类型对象的实例方法forEach()效率是最低的,而for each...in则的执行效率则是最高的,这种效率的差异随着遍历对象量级的提升而越发明显。
下面是我的验证代码:
package
{
import flash.display.Sprite;
import flash.utils.getTimer;
public class Main extends Sprite
{
//数组元素数量
private const itemNum:int = 1000000;
private var dataFor:Array = [];
private var dataForeach:Array = [];
private var dataForEach:Array = [];
//执行次数
private const time:int = 20;
public function Main()
{
for (var i:int = 0; i < time; i++)
{
dataFor.push( testFor( arrFactory() ) );
dataForeach.push( testForeach( arrFactory() ) );
dataForEach.push( testForEach( arrFactory() ) );
}
trace("for 循环遍历结果:"+dataFor,
"\nfor 循环遍历总时长: " + getTotalTime(dataFor) + " 毫秒");
trace("for each...in 循环遍历结果:"+dataForeach,
"\nfor each...in 循环遍历总时长: " + getTotalTime(dataForeach) + " 毫秒");
trace("somearray.forEach() 遍历结果:"+dataForEach,
"\nsomearray.forEach() 遍历总时长: " + getTotalTime(dataForEach) + " 毫秒");
}
//获取用于检测的数组
private function arrFactory():Array
{
var testArr:Array = [];
//初始化数组元素
for (var i:int = 0; i < itemNum; i++)
{
testArr.push( {index: i} );
}
return testArr;
}
//验证for循环
private function testFor(arr:Array):int
{
var time:int = getTimer();
for (var i:int = 0; i < itemNum; i++)
{
doSomething( arr[i] );
}
return getTimer() - time;
}
//验证 For each...in
private function testForeach(arr:Array):int
{
var startTime:int = getTimer();
for each(var item:Object in arr)
{
doSomething( item );
}
return getTimer() - startTime;
}
//验证 Array实例方法forEach()
private function testForEach(arr:Array):int
{
var startTime:int = getTimer();
arr.forEach( forEachCallback );
return getTimer() - startTime;
}
//调用Array实例的forEach方法所需的回调函数
private function forEachCallback(item:Object, i:int, arr:Array):void
{
doSomething(item);
}
//对数组元素做一些操作
private function doSomething(obj:Object):void
{
obj.time = getTimer();
}
//获取20次遍历过程的总时长
private function getTotalTime(arr:Array):int
{
var num:int = 0;
for each(var i:int in arr)
{
num += i;
}
return num;
}
}
}