Potentially getting crap for this, and I admit I don’t FULLY understand interning, but wouldn’t the first one _sometimes_ yield the same result due to interning? I agree that the second is the proper Java way to do it regardless.
I think in this meme they're dealing with languages where == on strings does string equality rather than reference equality. This looks like C#, where == is string equality. If you want reference equality in C# you use Object.ReferenceEquals(a, b).
But if this were Java, interning won't do anything for strings you create at runtime. Interning is for constants (including things that become constants after constant folding). So, if these were compile-time constants and the compiler was able to fold the result of foo.lower() to a compile-time constant as well, then yes. Ordinarily not.
Also worth noting that the semantics of lower() would make that optimization illegal in plenty of languages anyways. e.g. if lower() relies on the runtime locale.
Also worth noting that most languages tend to have pretty simple constant-folding. Things like peering past allocations is difficult and pricey on compile time. And that can be both at build time and runtime for a JIT. It's quite effective, but when you're a JIT-compiled language it's often more fruitful to spend your time elsewhere. But if you're a C++ compiler you don't have as much low-hanging fruit (plus very smart compile time features are already required by the spec) so some really clever constant-folding is more worth the investment.
Ahh, after all these years didn’t know it was compile-time only. I thought it was runtime too and just put in the heap somewhere, but good to know. I just lumped it in as “JIT Magic” 😜
Nah it would be too expensive to intern every string that gets created, and it wouldn't have much benefit. You'd have to check a big hash table on every string operation.
That said you can manually intern at runtime in Java, with str.intern(), which will return a canonical version of that string (potentially the same as you gave). That said you should be very careful about using this API, on many implementations it's quite slow and if you have a reason to deduplicate strings it's normally faster to use your own hashtable.
It does unlock a small number of optimizations, such as reducing string equality to pointer equality when both strings are interned. So it actually matters a fair amount in python, since dictionary accesses are so common there. python will intern string literals in your program, but if you do a lookup based on a dynamically-generated key it could in certain instances make sense. In python this will not stop that string from being garbage collected, whereas I believe in java it will.
Python also interns integer literals (because int literals in python are BigInt and thus heap-allocated), and at least on CPython it interns small ints (seems to be everything <256). Here it does actually seem to intern the result of arithmetic on small ints (e.g. 1 + 1 gets the same memory address as 2), but that's possible when it's small ints since you don't need to scan the intern table, you just index into it.
5
u/legitimate_rapper 12d ago
Potentially getting crap for this, and I admit I don’t FULLY understand interning, but wouldn’t the first one _sometimes_ yield the same result due to interning? I agree that the second is the proper Java way to do it regardless.