为什么字符串加载的速度比数字慢得多?

时间:2017-02-04 08:51:09

标签: javascript performance fibonacci

我写了一个脚本,目的是对Fibonacci序列进行排序(或任何两个数字将添加以制作下一个,然后是那两个,等等)。当您按下按钮时,该函数(称为fibonacci)将两个值相加,将新值推送到数组(称为序列),然后在数组中显示最新值。我用setInterval(称为递归)设置它,因此它继续向数组添加更多值,并显示更多数字。我正在试验这个功能,并想过尝试两个字符串而不是两个数字。它按预期工作,但它显着减慢,在五秒钟内崩溃浏览器。我想知道数字和字符串之间的区别是性能差异。

我的jsfiddle在这里:https://jsfiddle.net/MCBlastoise/yrr7fL4z/54/

这是我的代码:



var sequence = [0, 1];
var i = 2;
function recursion() {
	recur = setInterval(fibonacci, 1);
}
function fibonacci() {
	var current = document.getElementById("text");
	var a = sequence[i-2] + sequence[i-1];
	sequence.push(a);
	if (current.innerHTML === "") {
		current.innerHTML = sequence[0] + ", " + sequence[1] + ", " + sequence[2];
	}
	else {
		current.innerHTML = current.innerHTML + ", " + sequence[i];
	}
	i++;
};
function exactValue(position) {
	var current = document.getElementById("text");
	if (isNaN(position) === false && position % 1 === 0 && position >= 1) {
		if (position === 1) {
			current.innerHTML = sequence[0];
		}
		else if (position === 2) {
			current.innerHTML = sequence[1];
		}
		else {
			while (i !== position) {
				var a = sequence[i-2] + sequence[i-1];
				sequence.push(a);
				i++;
			}
			if (i === position) {
				current.innerHTML = "The value at position " + position + " is " + a + ".";
			}
		}
	}
}
function checkValue(value) {
	var current = document.getElementById("text");
	if (isNaN(value) === false) {
		if (value === 0) {
  		current.innerHTML = "The value provided appears at position " +	1 + ".";
 	 	}
    else if (value === 1) {
    	current.innerHTML = "The value provided appears at position " + 2 + ".";
    }
    else {
			while(a !== value && a !== Infinity) {
				var a = sequence[i-2] + sequence[i-1];
				sequence.push(a);
				i++;
			}
			if (a === value) {
				current.innerHTML = "The value provided appears at position " + i + ".";
	  	  return true;
			}
			if (a === Infinity) {
				current.innerHTML = "The value provided does not appear in 	this sequence.";
 	   		return false;
			}
     }
   }
}
function clear() {
	document.getElementById("text").innerHTML = "";
}

<div onclick="recursion(), clear()" style="cursor:pointer; background-color:black; width:30px; height:30px"></div>
<p id="text"></p>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:0)

好吧,将数字加载到内存中并添加它们通常可以编译为几个本机CPU指令,而连接字符串通常包括通过整个语言进行的大量函数调用以产生结果。而且我不确定JavaScript如何在内部处理字符串,但是增长字符串可能意味着为每个字符串分配一个全新的字节数组。

答案 1 :(得分:0)

当您将序列数组的元素更改为字符串时,以下行中的+运算符将执行完全不同的操作:

var a = sequence[i-2] + sequence[i-1];

这不是算术加法,而是字符串连接操作。这将涉及更多的内存和CPU时间:

增加两个数字:

  • 时间:常数,因为添加是作为CPU指令执行的,限制为64位浮点范围。
  • 内存:一个64位浮点数,因为数字在JavaScript中的表示方式。

两个字符串的连接:

  • 时间:根据输入字符串的长度呈线性:两个字符串中的每个字符都需要复制到新的内存位置
  • 内存:双打,因为最终字符串与两个输入字符串占用相同的内存

内存影响可能是杀死脚本的因素:仅经过20次迭代(即调用 fibonacci )后, a 的字符串值将具有超过10 000个字符,每次下一次迭代将继续几乎翻倍。经过30次迭代后, a 将拥有超过一百万个字符。如果你有足够的耐心等待这些兆字节的字符串复制增长到千兆字节,你会发现你的PC内存(JavaScript框中可用的部分)已经被完全吃掉了,可能在第40次迭代之前。