Just read something which caught my attention when reading the metaprogramming documentation:
Which states that one of the purposes of the :
is to create an interned string.
Apparently this is a type of string which is immutable, and stored in such a way that equality can be implemented in terms of identity, thus optimizing many algorithms which perform frequent string equal or not equal comparisons.
However, strings in Julia are immutable.
This raises a few questions
- are regular strings not stored in the same way which enables such comparison optimizations?
- if they are, why are strings and symbols different? (They both have “extra stuff”, eg methods, which the other does not have?)
- if they are not, then why is this same optimization not applied to regular strings?
There is a lot of overhead to interning a string, which wouldn’t be acceptable for generic runtime string manipulations.
It makes sense for symbols that are used in metaprogramming, because usually you only have a relatively small number of symbols, and runtime overhead in generating expressions is less of a concern (since expression generation usually occurs only once, at compile time). Symbols are also used for tagging types and other “symbolic label” purposes unrelated to metaprogramming, for which interning is important for performance — e.g. if you have a MyType{:foo}
, or are passing :foo
as an enum-like symbolic constant to a function.
That being said, if you have a specialized application where string interning makes sense, but you still want to support generic string operations like searching (which don’t work for Symbol
), you can use InternedStrings.jl — see also the discussion in [ANN] InternedStrings.jl: Allocate strings once and reuse them
3 Likes