I present StackCollections v0.2, in which I have completely rewritten the package from v0.1.
StackCollections.jl provides small, immutable isbits collections. Currently, it provides:
USet{U <: Unsigned} <: AbstractSet{UInt32}, an isbits bit set similar toBase.BitSet, but stored in a singleU. Basically a normal integer-as-bitset with anAbstractSetinterface.UVec{U <: Unsigned} <: AbstractVector{Bool}, an isbits bit vector similar toBase.BitVector, but stored in a singleU
Why use StackCollections.jl?
The types in StackCollections.jl are mostly useful as performance optimized implementations the Base equivalent of USet and UVec (which is BitSet or BitVector, respectively). If performance is not a concern, you can use the Base types and the StackCollections type don’t provide much extra.
However, if you do need extra performance, then the USet and UVec types are generally faster. They are small isbits types and so typically not heap allocated, and are stored inline in arrays. A USet{UInt8} is stored in a single byte. Most operations on the types are register-only ops and do not touch memory.
Right, but why use a package and not just write bit sets myself?
Integers as bit sets / bit vectors is a common trick and most programmers have implemented them many times. So why would you want to reach for a package for this basic functionality when you can implement it yourself easily?
- I already dealt with annoying edge cases: Did you think about how floats should be handled, such as
1.0? What about1e100which is not convertible toInteger? What about-0.0which is zero, but notisequalto0? What aboutmissing? Or1+0im? Logical indexing when it conflicts with masking? Etc etc. - Lots of non-obvious methods are already implemented. A small bit vector implementation is easy, but there is a ton of methods you could add specializations for. You probably won’t need specialized vararg
symdiffor specialized three-argumentreverse- but it’s nice it’s there. - StackCollections.jl is microoptimized. I did my best to avoid branches, outlined errors, and pulled all the bit tricks I (and Claude) could think of.
- The implementation is already well tested - so you don’t have to write tests for your ad hoc implementation.
History
StackCollections.jl was one of my first published Julia packages from 2019. When I wrote it I was a much worse programmer than I am now, hence the subpar v0.1 release and unfortunate package name - it probably should have been called BitsCollections.
Since making StackCollections.jl, I have used bit sets and bit vectors a few times, where I have ad hoc implemented them, always thinking that I should just use StackCollections.jl, but that I couldn’t be bothered to clean up the package.