Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are JavaScript strings immutable? Do I need a "string builder" in JavaScript?

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

like image 418
DevelopingChris Avatar asked Sep 09 '08 03:09

DevelopingChris


People also ask

Does JavaScript have string builder?

Several languages offer fast string-handling classes such as StringBuilder in . NET and StringBuffer/StringBuilder in Java. There are a number of ways to concatenate strings in JavaScript: str = "a" + "b"; str += "c"; str = str.

Are strings in JavaScript immutable?

String specifications among programming languages vary, however most languages treat them as reference types. But strings in JavaScript are different. They are immutable primitives. This means that the characters within them may not be changed and that any operations on strings actually create new strings.

Are string builders immutable?

StringBuilder is used to represent a mutable string of characters. Mutable means the string which can be changed. So String objects are immutable but StringBuilder is the mutable string type.

Does JavaScript have immutable?

In JavaScript String and Numbers are immutable data types. JavaScript is not a good language to work with data in an immutable fashion. In JavaScript Arrays and Objects are not immutable. Their values can be changed over time.


2 Answers

They are immutable. You cannot change a character within a string with something like var myString = "abbdef"; myString[2] = 'c'. The string manipulation methods such as trim, slice return new strings.

In the same way, if you have two references to the same string, modifying one doesn't affect the other

let a = b = "hello"; a = a + " world"; // b is not affected 

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 (Latest update in Ma5rch 2018), if you don't want to follow the link. The number on each test is in 1000 operations/second (higher is better)

Browser Index Push Concat SBIndex SBPush SBConcat
Chrome 71.0.3578 988 1006 2902 963 1008 2902
Firefox 65 1979 1902 2197 1917 1873 1953
Edge 593 373 952 361 415 444
Exploder 11 655 532 761 537 567 387
Opera 58.0.3135 1135 1200 4357 1137 1188 4294

Findings

  • Nowadays, all evergreen browsers handle string concatenation well. Array.join only helps IE 11

  • Overall, Opera is fastest, 4 times as fast as Array.join

  • Firefox is second and Array.join is only slightly slower in FF but considerably slower (3x) in Chrome.

  • Chrome is third but string concat is 3 times faster than Array.join

  • Creating a StringBuilder seems to not affect perfomance too much.

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, and feel free to add new links to different test cases below.

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

like image 105
Juan Mendes Avatar answered Oct 16 '22 11:10

Juan Mendes


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

like image 39
minty Avatar answered Oct 16 '22 11:10

minty