Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

Does javascript use immutable or mutable strings? Do I need a "string builder"?

share|improve this question
Yes, the y are immutable and you need a "string builder" of some sort. Read this blog.codeeffects.com/Article/String-Builder-In-Java-Script or this codeproject.com/KB/scripting/stringbuilder.aspx – Kizz Jul 14 '11 at 20:14
1  
Interesting, those examples contradict my findings in my answer. – Juan Mendes Feb 23 '12 at 19:29
add comment (requires an account with 50 reputation)

6 Answers

up vote 54 down vote accepted

from the rhino book:

In JavaScript, strings are immutable objects, which means that the characters within them may not be changed and that any operations on strings actually create new strings. Strings are assigned by reference, not by value. In general, when an object is assigned by reference, a change made to the object through one reference will be visible through all other references to the object. Because strings cannot be changed, however, you can have multiple references to a string object and not worry that the string value will change without your knowing it

share|improve this answer
6  
Link to an appropriate section of the rhino book: books.google.com/… – baudtack Jun 6 '09 at 5:55
Thanks, I didn't know that. – Tarik Sep 8 '09 at 21:10
add comment (requires an account with 50 reputation)

They are immutable. However, I've always heard what Ash mentioned in his answer( that using Array.join is faster for concatenation) so I wanted to test out the different methods of concatenating strings and abstracting the fastest way into a StringBuilder. I wrote some tests to see if this is true (it isn't!).

This was what I believed would be the fastest way, though I kept thinking that adding a method call may make it slower...

function StringBuilder() {
  this._array = [];
  this._index = 0;
}

StringBuilder.prototype.append = function (str) {
    this._array[this._index] = str;
    this._index++;
}

StringBuilder.prototype.toString = function () {
  return this._array.join('');
}

Here are performance speed tests. All three of them create a gigantic string made up of concatenating "Hello diggity dog" one hundred thousand times into an empty string.

I've created three types of tests

  • Using Array.push and Array.join
  • Using Array indexing to avoid Array.push, then using Array.join
  • Straight string concatenation

Then I created the same three tests by abstracting them into StringBuilderConcat, StringBuilderArrayPush and StringBuilderArrayIndex http://jsperf.com/string-concat-without-sringbuilder/5 Please go there and run tests so we can get a nice sample. Note that I fixed a small bug, so the data for the tests got wiped, I will update the table once there's enough performance data. Go to http://jsperf.com/string-concat-without-sringbuilder/5 for the old data table.

Here are some numbers from Feb 21, 2013, if you don't want to follow the link. The number on each test is in operations/second (higher is better)

| Browser          | Index | Push | Concat | SBIndex | SBPush | SBConcat |
---------------------------------------------------------------------------
| Chrome 24.0.1312 | 83    | 87   | 702    | 69      | 87     | 165      |
| Chrome 25.0.1364 | 43    | 47   | 620    | 42      | 42     | 68       |
| Firefox 10.0.10  | 164   | 164  | 533    | 164     | 16     | 421      |
| Firefox 19.0     | 70    | 70   | 259    | 70      | 70     | 186      |
| Exploder 7.0     | 51    | 33   | 58     | 31      | 37     | 45       |
| Exploder 8.0     | 48    | 30   | 58     | 30      | 36     | 36       |
| Exploder 9.0     | 87    | 64   | 95     | 61      | 61     | 61       |
| Opera 12.14      | 125   | 154  | 66     | 106     | 137    | 63       | 

Findings

  • Nowadays, all browsers handle string concatenation well. Array.join only helps Opera

  • Overall, Chrome is fastest, clocking 1025 ops/sec in 27.0. 10 times faster than using Array.join()

  • Firefox is in second place at around 550 ops/sec (but 20.0 seems to have regressed). Array.join is about 4-5 times slower.

  • IE is fastest with straight string concatenation, it's really slow using Array.join and Array.push. IE 9 makes Array.join not be so slow, and all the SB abstractions perform almost the same way (probably because of the method overhead)

  • Opera is the only one where the Array.join actually helps, it's 2-3 times as fast as string concatenation.

  • Creating a StringBuilder to abstract away each browser's performance issues does more harm than good. The overhead of method calls may be acceptable but the tendency seems to be that browsers are handling string concatenation more smartly. It would only make sense if your target audience is Opera, so you can use Array.join there and use String concatenation everywhere else (this means all the other browsers are taking a hit)

Hope somebody else finds this useful

Different Test Case

Since @RoyTinker thought that my test was flawed, I created a new case that doesn't create a big string by concatenating the same string, it uses a different character for each iteration. String concatenation still seemed faster or just as fast. Let's get those tests running.

I suggest everybody should keep thinking of other ways to test this, thanks for the input Roy.

http://jsperf.com/string-concat-without-sringbuilder/7

share|improve this answer
3  
This is a great posting. Thanks for taking the time to code and measure these implementations. – stackoverflowuser2010 Jun 30 '11 at 18:09
1  
+1 for such good work ! :) – dotNetSoldier Nov 21 '12 at 12:29
   
@Juan, the link you asked us to visit concatenates a 112-char string 30 times. Here's another test that might help balance things - Array.join vs string concatenation on 20,000 different 1-char strings (join is much faster on IE/FF). jsperf.com/join-vs-str-concat-large-array – Roy Tinker Jul 22 at 18:03
@RoyTinker Roy, oh Roy, your tests are cheating because you're creating the array in the setup of the test. Here's the real test using different characters jsperf.com/string-concat-without-sringbuilder/7 Feel free to create new test cases, but creating the array is part of the test itself – Juan Mendes Jul 22 at 18:11
@JuanMendes My goal was to narrow the test case to a strict comparison of join vs string concatenation, hence building the array prior to the test. I don't think that's cheating if that goal is understood (and join enumerates the array internally, so it's not cheating to omit a for loop from the join test, either). – Roy Tinker Jul 22 at 18:18
show 2 more commentsadd comment (requires an account with 50 reputation)

Performance tip:
If you have to concatenate large strings, put the string parts into an array and use the Array.Join() method to get the overall string. This can be many times faster for concatenating a large number of strings.

No StringBuilder in javascript.

share|improve this answer
I know there isn't a stringBuilder, msAjax has one, and I was just pondering whether or not its useful – DevelopingChris Sep 9 '08 at 3:56
2  
What does this have to do with strings being immutable or not? – baudtack Jun 6 '09 at 5:56
4  
@docgnome: Because strings are immutable, string concatenation requires creating more objects than the Array.join approach – Juan Mendes Jan 17 '11 at 20:37
1  
According to Juan's test above, string concatenation is actually faster in both IE and Chrome, while slower in Firefox. – Bill Yang Feb 21 '12 at 18:36
add comment (requires an account with 50 reputation)

JavaScript strings are indeed immutable.

share|improve this answer
Doc link? I can't find any specifics on this. – DevelopingChris Sep 9 '08 at 3:50
"attempting to set an individual character won't work" -- developer.mozilla.org/en/JavaScript/Reference/Global_Objects/… – Ken Feb 27 '11 at 4:54
add comment (requires an account with 50 reputation)

Strings in Javascript are immutable

share|improve this answer
add comment (requires an account with 50 reputation)

Regarding your question (in your comment to Ash's response) about the StringBuilder in ASP.NET Ajax the experts seem to disagree on this one.

Christian Wenz says in his book Programming ASP.NET AJAX (O'Reilly) that "this approach does not have any measurable effect on memory (in fact, the implementation seems to be a tick slower than the standard approach)."

On the other hand Gallo et al say in their book ASP.NET AJAX in Action (Manning) that "When the number of strings to concatenate is larger, the string builder becomes an essential object to avoid huge performance drops."

I guess you'd need to do your own benchmarking and results might differ between browsers, too. However, even if it doesn't improve performance it might still be considered "useful" for programmers who are used to coding with StringBuilders in languages like C# or Java.

share|improve this answer
add comment (requires an account with 50 reputation)

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.