3 ms·
> (From the Node.js GitHub issue.) Sounds like this guy is mixing up his Java knowledge with C++ knowledge. That is exactly it. C++ string streams have had atr
by juunpp 3y ago
> (From the Node.js GitHub issue.) Sounds like this guy is mixing up his Java knowledge with C++ knowledge.
That is exactly it. C++ string streams have had atrocious performance since forever. Good abstraction, not very useful in practice.
In Java, if I remember correctly, strings are immutable, so the StringBuilder or whatever ridiculous name it had was the faster way to build a string.
> "I recently learned that some Node.js engineers prefer stream classes when building strings, for performance reasons."
Pretty much tells you everything you need to know about node js, I guess.
- Rebelgecko 3y agoFor what it's worth, even in Java the compiler is often smart enough to replace naive string concatenation with equivalent StringBuilder usage (although I don't know if it is smart enough to do that in a for loop like this)
- throwaway2037 3y agoTo less informed readers, "smart enough" hear means: Imagine you have two Java Strings: a and b If you write the Java code: String c = a + b; The Java compiler will roughly replace this code with: String c = new StringBuilder(a).append(b).toString(); I'm not sure I would say this is "smart". Rather, it is just a hack to allow Strings to override the plus (+) operator. Normally, Java does not allow operator overidding, like C++.
- masklinn 3y agoTwo things: First, it has nothing to do with overriding the + operator, the operation is statically decidable so the compiler is perfectly aware that this is a string concatenation (not a numerical addition) and string is a special builtin, the compiler can generate anything it wants. Which is exactly what it does, they just originally decided to implement string concatenation as stringbuffer/stringbuilder ops. Meanwhile the addition of integers, longs, floats, and doubles are (or were anyway) different bytecode ops. This does not require general purpose operator overloading support. Builtins are not limited to the language’s user level semantics. And second OpenJDK has not done that since Java 9 (JEP 280), the compiler now emits generic “string concatenation” bytecode for the runtime / jit to deal with.
- masklinn 3y agoIt’s not, and they basically gave up on it. Historically the OpenJDK would compile direct concatenation to StringBuilder so e.g. a += b + c; Would become something like StringBuilder sb = new StringBuilder(); sb.append(a); sb.append(b); sb.append(c); a = sb.toString(); However it was never capable of doing such an optimisation across loops. In Java 9, they gave up on such static optimisations, instead the compiler now emits dedicated string concatenation bytecode (see JEP 280), which the runtime (and JIT) can then hook into. Does that handle loops? Unclear. Benchmarks / testimonies from back then (java9/java10 days) hint that no, direct concatenation remains much slower than StringBuilder. But I didn’t find anything super recent so maybe they improved the behaviour in the meantime.
- paulddraper 3y ago> "I recently learned that some Node.js engineers prefer stream classes when building strings, for performance reasons." Pretty much tells you everything you need to know about node js, I guess. Google Closure Library includes a StringBuffer class. [1] I recall it having explanatory notes, but I don't see them in the code now. JavaScript engines can optimize a string concatenating to in-place edit, if there is only one reference to the first string. The StringBuffer class keeps the reference count at one, guaranteeing this optimization is available, even if the StringBuffer itself is ever shared. [1] https://github.com/google/closure-library/blob/master/closure/goog/string/stringbuffer.js https://github.com/google/closure-library/blob/master/closur...