[ANN] EnumSets.jl

jw3126
Tue, 10 Dec 2024 17:51:24 +0000
Package Announcements

I am pleased to announce EnumSets.jl. From the readme:

EnumSets

This packages allows to create a very fast immutable type that represents a set of enum values.

julia> using EnumSets

julia> @enum Lang Python Julia C

julia> @enumset LangSet <: EnumSet{Lang}

julia> s = LangSet((Python, Julia))
LangSet with 2 elements:
  Python
  Julia

julia> push(s, C) # s is immutable, but we can create modified copies
LangSet with 3 elements:
  Python
  Julia
  C

julia> s
LangSet with 2 elements:
  Python
  Julia

julia> s2 = LangSet((C, Python))
LangSet with 2 elements:
  Python
  C

julia> s ∪ s2
LangSet with 3 elements:
  Python
  Julia
  C

julia> s ∩ s2
LangSet with 1 element:
  Python

...

Performance

using EnumSets

@enum Alphabet A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

function workout(sets)
    s = first(sets)
    b = false
    ESet = eltype(sets)
    E = eltype(ESet)
    for s1 in sets
        for s2 in sets
            for e in instances(E)
                s = (s ∩ s2) ∪ s1
                s = s ∪ s1
                s = symdiff(s, ESet((e,)))
                b = b ⊻ (s1 ⊆ s2)
                b = b ⊻ (s1 ⊊ s2)
                b = b ⊻ (e in s)
            end
        end
    end
    s, b
end

@enumset AlphabetSet <: EnumSet{Alphabet}

sets = [AlphabetSet(rand(instances(Alphabet)) for _ in 0:length(instances(Alphabet))) for _ in 1:100]
basesets = map(Set, sets)

# warmup
workout(sets, )
workout(basesets, )
# benchmark
println(eltype(sets))
res1 = @time workout(sets, )
println(eltype(basesets))
res2 = @time workout(basesets, )

@assert res1 == res2 # both yield the same result

# AlphabetSet
#   0.000279 seconds (1 allocation: 16 bytes)
# Set{Alphabet}
#   0.503022 seconds (8.15 M allocations: 756.469 MiB, 13.51% gc time)

7 posts - 3 participants