Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/410.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么字符串的加载速度比数字慢得多?_Javascript_Performance_Fibonacci - Fatal编程技术网

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

Javascript 为什么字符串的加载速度比数字慢得多?,javascript,performance,fibonacci,Javascript,Performance,Fibonacci,我写了一个脚本,目的是对斐波那契序列(或任何两个数字加起来构成下一个数字,然后是这两个数字,以此类推)进行排序。按下按钮时,函数(称为fibonacci)将两个值相加,将新值推入数组(称为序列),然后显示数组中最近的值。我使用setInterval(称为递归)设置它,因此它继续向数组添加更多值,并显示更多数字。我正在试验这个函数,并想尝试两个字符串而不是两个数字。它按预期工作,但速度明显减慢,在五秒钟内使浏览器崩溃。我想知道数字和字符串在性能上有什么不同 我的JSFIDLE在这里: 这是我的代码

我写了一个脚本,目的是对斐波那契序列(或任何两个数字加起来构成下一个数字,然后是这两个数字,以此类推)进行排序。按下按钮时,函数(称为fibonacci)将两个值相加,将新值推入数组(称为序列),然后显示数组中最近的值。我使用
setInterval
(称为递归)设置它,因此它继续向数组添加更多值,并显示更多数字。我正在试验这个函数,并想尝试两个字符串而不是两个数字。它按预期工作,但速度明显减慢,在五秒钟内使浏览器崩溃。我想知道数字和字符串在性能上有什么不同

我的JSFIDLE在这里:

这是我的代码:

var序列=[0,1];
var i=2;
函数递归(){
recur=设定间隔(斐波那契,1);
}
函数fibonacci(){
var current=document.getElementById(“文本”);
var a=序列[i-2]+序列[i-1];
序列推送(a);
如果(current.innerHTML==“”){
current.innerHTML=序列[0]+“,“+序列[1]+”,“+序列[2];
}
否则{
current.innerHTML=current.innerHTML+“,”+序列[i];
}
i++;
};
函数值(位置){
var current=document.getElementById(“文本”);
如果(isNaN(位置)==false&&position%1==0&&position>=1){
如果(位置===1){
current.innerHTML=序列[0];
}
否则如果(位置===2){
current.innerHTML=序列[1];
}
否则{
而(i!==位置){
var a=序列[i-2]+序列[i-1];
序列推送(a);
i++;
}
如果(i==位置){
current.innerHTML=“位置“+position+”处的值为“+a+”;
}
}
}
}
函数校验值(值){
var current=document.getElementById(“文本”);
如果(isNaN(值)==false){
如果(值==0){
current.innerHTML=“提供的值显示在位置“+1+”;
}
else if(值===1){
current.innerHTML=“提供的值显示在位置“+2+”;
}
否则{
while(a!==值&&a!==无穷大){
var a=序列[i-2]+序列[i-1];
序列推送(a);
i++;
}
如果(a==值){
current.innerHTML=“提供的值显示在位置“+i+”;
返回true;
}
if(a==无穷大){
current.innerHTML=“提供的值不在此序列中显示。”;
返回false;
}
}
}
}
函数clear(){
document.getElementById(“文本”).innerHTML=“”;
}


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

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

var a = sequence[i-2] + sequence[i-1];
这将是一个字符串串联操作,而不是算术加法。这将涉及更多的内存和CPU时间:

添加两个数字:
  • 时间:常数,因为加法作为CPU指令执行,限制在64位浮点范围内
  • 内存:一个64位浮点,因为这是JavaScript中数字的表示方式
两个字符串的串联:
  • 时间:输入字符串的长度是线性的:两个字符串中的每个字符都需要复制到新的内存位置
  • 内存:加倍,因为最后一个字符串与两个输入字符串一起占用相同的内存

内存影响可能是终止脚本的因素:仅经过20次迭代(即调用fibonacci)后,a的字符串值的长度将超过10000个字符,这将继续几乎是下一次迭代的两倍。经过30次迭代后,一个脚本将有100多万个字符。如果你有足够的耐心等待这些兆字节的字符串复制增长到千兆字节,你会发现你电脑的内存(JavaScript框可用的部分)已经被完全消耗了,可能在第40次迭代之前。

挑剔:间隔调用函数不是递归。是的,我知道。老实说,我只是给我的函数起了唯一的名字,我会记住的。我之所以给它命名,是因为我在某个地方读到斐波那契序列被称为递归公式。“…想尝试两个字符串而不是两个数字”:我们在代码中看到这两个字符串在哪里?@trincot最初,正如代码中所见,“序列”数组的两个值是数字:
0
1
。但是,我后来用各种字符串对它进行了测试,包括
“0”
“1”
。好的,从问题中不清楚您实际更改了什么。由于斐波那契是为数字定义的,您能解释一下字符串的输出是什么吗?也许是这样的<代码>[“0”、“1”、“01”、“101”、“01101”、“10101101”、“10101101”…],或者您希望“添加”如何工作?你能澄清一下这个问题吗?这是一个很好的答案,在我测试它之前,我怀疑可能是这样的。出于好奇,简单地将两个数字相加,然后将它们添加到一个空字符串中,并将“连接”的字符串推送到数组中,是否需要与平常一样多的内存:
var a=sequence[i-2]+sequence[i-1]
stringValue=a+“”
sequence.push(stringValue)不客气。你提出的替代方案会很好地发挥作用,就像时间一样