Why Is String Concatenation Faster Than Array Join

Why is string concatenation faster than array join?

Browser string optimizations have changed the string concatenation picture.

Firefox was the first browser to optimize string concatenation. Beginning with version 1.0, the array technique is actually slower than using the plus operator in all cases. Other browsers have also optimized string concatenation, so Safari, Opera, Chrome, and Internet Explorer 8 also show better performance using the plus operator. Internet Explorer prior to version 8 didn’t have such an optimization, and so the array technique is always faster than the plus operator.

— Writing Efficient JavaScript: Chapter 7 – Even Faster Websites

The V8 javascript engine (used in Google Chrome) uses this code to do string concatenation:

// ECMA-262, section 15.5.4.6
function StringConcat() {
if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
throw MakeTypeError("called_on_null_or_undefined", ["String.prototype.concat"]);
}
var len = %_ArgumentsLength();
var this_as_string = TO_STRING_INLINE(this);
if (len === 1) {
return this_as_string + %_Arguments(0);
}
var parts = new InternalArray(len + 1);
parts[0] = this_as_string;
for (var i = 0; i < len; i++) {
var part = %_Arguments(i);
parts[i + 1] = TO_STRING_INLINE(part);
}
return %StringBuilderConcat(parts, len + 1, "");
}

So, internally they optimize it by creating an InternalArray (the parts variable), which is then filled. The StringBuilderConcat function is called with these parts. It's fast because the StringBuilderConcat function is some heavily optimized C++ code. It's too long to quote here, but search in the runtime.cc file for RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) to see the code.

Array Join vs String Concat

String concatenation is faster in ECMAScript. Here's a benchmark I created to show you:

http://jsben.ch/#/OJ3vo

Why is 'join' faster than normal concatenation?

The code in a join function knows upfront all the strings it’s being asked to concatenate and how large those strings are, and hence it can calculate the final string length before beginning the operation.

Hence it needs only allocate memory for the final string once and then it can place each source string (and delimiter) in the correct place in memory.

On the other hand, a single += operation on a string has no choice but to simply allocate enough memory for the final string which is the concatenation of just two strings. Subsequent +='s must do the same, each allocating memory which on the next += will be discarded. Each time the evergrowing string is copied from one place in memory to another.

Which way is better in Javascript, string concatenation or with array?

This answers your question: High-performance String Concatenation in JavaScript

Is list join really faster than string concatenation in python?

From Efficient String Concatenation in Python

Method 1 : 'a' + 'b' + 'c'

Method 6 : a = ''.join(['a', 'b', 'c'])

20,000 integers were concatenated into a string 86kb long :

pic

                Concatenations per second     Process size (kB)
Method 1 3770 2424
Method 6 119,800 3000

Conclusion : YES, str.join() is significantly faster then typical concatenation (str1+str2).

Ruby - Array.join versus String Concatenation (Efficiency)

Try it yourself with the Benchmark class.

require "benchmark"

n = 1000000
Benchmark.bmbm do |x|
x.report("concatenation") do
foo = ""
n.times do
foo << "foobar"
end
end

x.report("using lists") do
foo = []
n.times do
foo << "foobar"
end
string = foo.join
end
end

This produces the following output:

Rehearsal -------------------------------------------------
concatenation 0.300000 0.010000 0.310000 ( 0.317457)
using lists 0.380000 0.050000 0.430000 ( 0.442691)
---------------------------------------- total: 0.740000sec

user system total real
concatenation 0.260000 0.010000 0.270000 ( 0.309520)
using lists 0.310000 0.020000 0.330000 ( 0.363102)

So it looks like concatenation is a little faster in this case. Benchmark on your system for your use-case.

String.join() vs other string concatenation operations

String.join relies on the class StringJoiner which itself relies on an internal StringBuilder to build the joined string.

So performance-wise it's much the same as using a StringBuilder and appending to it, or using a chain of + (which nowadays are converted to StringBuilder operations by the compiler).

But the significance of String.join is not as a general replacement for + or String.concat, but in being the "reverse operation" of a String.split operation. It makes more sense in that context - when you have a bunch of strings that you want to join together using a delimiter - than as a replacement for concat.

That is, to build an output like "a/b/c/d" or "(a+b+c+d)" when you have a,b,c and d in an array or a list, String.join or a StringJoiner would make the operation clear and readable.



Related Topics



Leave a reply



Submit