4 ms·
> I can only think of a few other optimizations that affect memory usage Java has string interning. I think that’s a hack that shouldn’t exist in an ideal worl
by Someone 2mo ago
> I can only think of a few other optimizations that affect memory usage
Java has string interning. I think that’s a hack that shouldn’t exist in an ideal world. Reason is that, as a library writer, you cannot make the call whether to intern strings (requiring more instructions for string access, thus slowing down code, but decreasing memory usage, and, because of that, possibly speeding up the code again) or not.
- vanderZwan 2mo ago> requiring more instructions for string access Wait, why would interned immutable strings require more instructions when doing regular string access? You can still point to the start of a zero-terminated C-string, it just requires storing extra metadata like lenght and a string hash somewhere. Which can be done at the negative indices of said pointer. Or do you refer to the extra rolling-hash pass needed when concatenating two strings to verify if it would result in an already-interned one? Because yes, that's one extra rolling hast pass over the appended string the first time a string is constructed, but after that doing so again likely saves memory and construction time, because any concatenation that would result in an already interned string would avoid actual memory allocation and copying of the string's characters. Plus string comparisons become cheap O(1) pointer comparisons this way, which is really nice in many use-cases. And that's not even considering more advanced tricks like interning short strings in the 64-bit word of the pointer to the string itself, relying on the fact that modern memory allocators never return an address with the lsb set, so it can be used to flag it as such[0]. [0] https://squoze.org/ https://squoze.org/
- amiga386 2mo ago> Wait, why would interned immutable strings require more instructions when doing regular string access? Java automatically interns static strings (e.g. from class files), but does not automatically intern dynamically-allocated strings, e.g. new String(charArray) If you want it interned, you have to intentionally call e.g. new String(...).intern(). If you do this on every string you work with, you can then reliably use reference equality instead of value equality, e.g. given char[] abc = {'a','b','c'}; then new String(abc) != new String(abc) != "abc" but new String(abc).intern() == new String(abc).intern() == "abc" But if you're interning every string, you're doing extra work to maintain that string pool, and adding extra pressure on the GC, and potentially you'll be re-interning strings a lot depending on how many times they end up no longer referenced by the time GC runs.
- vanderZwan 2mo agoThanks to both of you for explaining, I thought Java and JavaScript would have similar behavior here and did not know .intern() had to be manually invoked in the former. Just to clarify where I started from: JS has the notion of String Primitives and String Objects[0], and concatenating two string primitives results in another string primitive. It's as if it always calls .intern(). Except, since from a user perspective there is no option to not intern it, JS implementations are free to do optimizations that don't seem available to Java. Like avoiding heap allocation for provably short-lived strings in the first place, and not interning them if they are never compared (I don't actually know if it does those optimizations, but I imagine it shouldn't be too hard to prove these things with many short functions). [0] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#string_primitives_and_string_objects https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- Someone 2mo ago> Wait, why would interned immutable strings require more instructions when doing regular string access Sorry, I wasn’t precise. Accessing them won’t take more instructions, but setting them up does. > Or do you refer to the extra rolling-hash pass needed when concatenating two strings to verify if it would result in an already-interned one? I don’t think the JVM does that.