当前位置: 代码迷 >> Web前端 >> 尽信书不如无书―循环性能的对照
  详细解决方案

尽信书不如无书―循环性能的对照

热度:63   发布时间:2013-10-12 11:54:02.0
尽信书不如无书―循环性能的对比

记得之前看过《高性能javascript》,里面比较了一下循环的性能,比如下面四种循环

for (var i = 0, item; i < array.length; i++) {
	item = array[i];
}
for (var i = 0,item,length=array.length; i < length; i++) {
    item = array[i];
}
for (var i = 0,item; item = array[i]; i++) {
    var tmp = item;
}
var i = array.length;
var item;
while(i--){
    item = array[i];
}

书上的结论是最后一种最快,而第一种最慢。

现如今做了下测试,发现,书上的结论不完全是正确的,先给出测试结果截图~

chrome 30 下的结果

IE10 下的结果

 

IE其他版本下的结果,受限于环境影响,这里的测试使用IEtester,结果仅供参考,这里的每次循环从0到100000其实重复执行了1000次,下面附上源代码

根据测试结果大致能看出来,老浏览器的话,上面第四种循环性能确实最好,但是最新的浏览器应该是对循环做了不错的优化,所以情况会不太一样,

而且这里IE10有些奇怪,如果打开F12的开发者工具的话,IE10的结果会变成下图这样

之前的循环2和循环4,应该是很快的,打开开发者工具后又变慢了,尤其是循环4,

不过这里综合来看的话,循环二应该是推荐使用的循环方式了,在所有测试中基本都是比较快的,而不是最后一种循环。


源代码

benchmark.js

(function(exports){
	function init(name){
		var heading = document.createElement("h2");
		heading.innerHTML = name;
		document.body.appendChild(heading);

		var ol = document.createElement("ol");
		document.body.appendChild(ol);
		return ol;
	}

	function runTest(tests, view, iterations){
		for(var label in tests){
			if(!tests.hasOwnProperty(label) || !/Function/i.test(typeof(tests[label]))){
				continue;
			}
		
			(function(name,test){
				setTimeout(function(){
					var start = new Date().getTime();
					var l = iterations;

					while(l--){
						test();
					}

					var total = new Date().getTime() - start;

					var li = document.createElement("li");
					li.innerHTML = name + ": " + total +
					"ms (total), " + (total / iterations) +
					"ms (avg)";
					view.appendChild(li);

				},15);
				
			})(label,tests[label]);
		}
	}

	function benchmark(name, tests, iterations) {
		iterations = iterations || 1000;
		var view = init(name);
		runTest(tests, view, iterations);
	}

	exports.benchmark = benchmark;
})(window);

index.html

<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
	</head>
	<body>
		<script type="text/javascript" src="benchmark.js"></script>

		<script type="text/javascript">
			var loopLength = 100000;
			var array = [];
			for (var i = 0; i < loopLength; i++) {
				array[i] = "item" + i;
			}
			
			benchmark("Loop performance", {

				"for-loop": function () {
					for (var i = 0, item; i < array.length; i++) {
						item = array[i];
					}
				},
				
				"reversed-for-loop": function () {
					var length=array.length;
					for (var i = length-1; i; i--) {
						var item = array[i];
					}
				},
				
				"optimised-for-loop-1": function () {
					for (var i = 0,item,length=array.length; i < length; i++) {
						item = array[i];
					}
				},

				"optimised-for-loop-2":function(){
					for (var i = 0,item; item = array[i]; i++) {
						var tmp = item;
					}
				},

				"reversed-while-loop":function(){
					var i = array.length;
					var item;
					while(i--){
						item = array[i];
					}
				}
			});
		</script>
	</body>
</html>