简体   繁体   中英

Why do strings load so much slower than numbers?

I wrote a script with the purpose of sequencing the Fibonacci Sequence (or any two numbers that would add to make the next, and then those two, etc.). When you press a button, the function (called fibonacci) adds the two values together, pushes the new value into an array (called sequence), and then displays the most recent value in the array. I set it up with a setInterval (called recursion), so it continues to add more values to the array, and display more numbers. I was experimenting with the function, and thought to try two strings instead of two numbers. It worked as expected, however it slowed down significantly, crashing the browser within the span of five seconds. I was wondering what the difference would be, performance-wise, between numbers and strings.

My jsfiddle is here: https://jsfiddle.net/MCBlastoise/yrr7fL4z/54/

And here is my code:

 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> 

Well, loading numbers into memory and adding them can usually be compiled to just a few native CPU instructions, while concatenating Strings usually includes a lot of function calls through the whole language to produce a result. And I'm not sure how JavaScript handles strings internally, but growing a string could mean allocating a whole new byte array for each one.

When you change the elements of the sequence array to be strings, the + operator in the following line will perform a completely different operation:

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

Instead of an arithmetic addition, this will be a string concatenation operation. This will involve a lot more memory and CPU time:

Addition of two numbers:

  • Time: constant, since an addition is performed as a CPU instruction, limited to the 64-bit float range.
  • Memory: one 64-bit float, since that is how numbers are represented in JavaScript.

Concatenation of two strings:

  • Time: linear in terms of the length of the input strings: each character from both strings needs to be copied to a new memory location
  • Memory: doubles, as the final string occupies the same memory as the two input strings together

The memory impact will probably be the factor that kills the script: after only 20 iterations (ie calls to fibonacci ) the string value of a will have a length of over 10 000 characters, which will continue to almost double each next iteration. After 30 iterations, a will have more than a million characters. If you have enough patience to wait for the string copying of those megabytes to grow to gigabytes you'll find your PC's memory (the part available to the JavaScript box) has been eaten completely, probably before the 40th iteration.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM