ValueSymbols
The module ValueSymbols
provides a wrapper type ValueSymbol
for
Julia Symbols, implemented as pointerfree "bitstype". This allows
storing ValueSymbol
objects very efficiently in immutable types or
tuples with other bitstype types. Regular Symbol
objects are stored
as pointers, hence are not bitstypes, and hence currently require heap
allocation.
using ValueSymbols
sym = :car
isbits(sym)
vsym = ValueSymbol(sym)
isbits(vsym)
ValueSymbol
is a bitstype, while Symbol
is not.
This is the practical consequence:
@time Pair{Symbol,Int}[:car => i for i in 1:1000000];
0.082046 seconds (1.00 M allocations: 38.147 MB, 79.57% gc time)
@time Pair{ValueSymbol,Int}[ValueSymbol(:car) => i for i in 1:1000000];
0.006780 seconds (2 allocations: 15.259 MB)
Creating tuples or pairs containing symbols requires one heap
allocation per tuple or pair. If you use a ValueSymbol
instead,
these allocations are avoided.
Examples
Convert between symbols and value symbols:
using ValueSymbols
sym = :car
vsym = ValueSymbol(sym)
sym2 = Symbol(vsym)
@assert sym2 === sym
Converting to a value symbol and back gives the original symbol.
Comparisons:
using ValueSymbols
sym = :car
vsym = ValueSymbol(sym)
@assert vsym == sym
Value symbols and symbols can be compared directly. Note that this
works only with the regular comparison operator ==
, not with the
object identity comparison ===
, as the latter is always different
for different types.
Value symbols also define an ordering. This ordering is based on the symbols' name, same as for Julia's regular symbols:
@assert :car < :plane
@assert ValueSymbol(:car) < ValueSymbol(:plane)