Skip to content

Instantly share code, notes, and snippets.

@rickhull
Last active March 19, 2024 20:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rickhull/08b4f030a961bc764742aa614bdde5eb to your computer and use it in GitHub Desktop.
Save rickhull/08b4f030a961bc764742aa614bdde5eb to your computer and use it in GitHub Desktop.
bitset benchmark
require 'rbconfig/sizeof' # can we use 64 bit ints?
require 'benchmark/ips'
require 'bitset'
# this should work well up to 64 bits on 64 bit platforms
# using native integers
# beyond that, Bignums will be generated
class BitsInt
attr_reader :int
def initialize(num_bits, ingest: false)
@int = ingest ? (2**num_bits / 3r).to_i : 0
end
def set(*bits)
@int |= bits.uniq.sum { |bit| 1 << bit }
end
def set?(*bits)
bits.all? { |bit| @int[bit] != 0 }
end
end
class BitsArray
attr_reader :ary
def initialize(num_bits, ingest: false)
if ingest
@ary = Array.new(num_bits) { |i| i % 2 == 0 ? true : false }
else
@ary = Array.new(num_bits) { false }
end
end
def set(bits)
bits.each { |b| @ary[b] = true }
end
def set?(bits)
@ary.values_at(*bits).all?
end
end
class BitSahlGood
# in bits, e.g. 64 bit / 32 bit platforms. SIZEOF returns byte width
INT_WIDTH = RbConfig::SIZEOF.fetch('long') * 8
def initialize(num_bits, ingest: false)
init = ingest ? (2**INT_WIDTH / 3r).to_i : 0
@storage = [init] * (num_bits / INT_WIDTH.to_f).ceil
end
def set(bits)
bits.each { |b|
slot, val = b.divmod(INT_WIDTH)
@storage[slot] |= (1 << val)
}
end
def set?(bits)
bits.all? { |b|
slot, val = b.divmod(INT_WIDTH)
@storage[slot][val] != 0
}
end
end
def rand_bits(num, bitmax)
Array.new(num) { rand(bitmax) }
end
# we're gonna pregenerate a large number of random bit indices
NUM_RAND_BITS = 1000
POWERS = [6, 8, 10, 12, 14, 16, 18, 20]
RAND_BITS = POWERS.map { |bitpow|
[bitpow, rand_bits(NUM_RAND_BITS, 2**bitpow)]
}.to_h
INCLUDE_BITSET = true
INCLUDE_BITSINT = true
INCLUDE_BITSARRAY = true
INCLUDE_BITSAHLGOOD = true
# we can't do fancy integer math for Bitset ingestion
# so pregenerate the Bitsets with all even bits on
BITSETS = POWERS.map { |bitpow|
[bitpow, Bitset.from_s('10' * (2**(bitpow - 1)))]
}.to_h
# let's make it fair to BitSahlGood, even though it has fast ingestion
BSGS = POWERS.map { |bitpow|
[bitpow, BitSahlGood.new(2**bitpow, ingest: true)]
}.to_h
puts "FINISHED PREGENERATION"
puts
# try different bits per entry
num_bits = 7
POWERS.each { |bitpow|
bitmax = 2**bitpow
puts "=" * 40
puts "\t 2^#{bitpow} (#{bitmax}) bits"
puts "=" * 40
puts
Benchmark.ips { |b|
b.warmup = 0.2
b.time = 2
# uses a pregenerated bitmap
if INCLUDE_BITSET
b.report("Bitset 2^#{bitpow} (#{bitmax} bits)") {
bitset = BITSETS.fetch(bitpow)
RAND_BITS.fetch(bitpow).each_slice(num_bits) { |bits|
bitset.set?(*bits)
}
}
end
if INCLUDE_BITSINT
b.report("BitsInt 2^#{bitpow} (#{bitmax} bits)") {
bitset = BitsInt.new(bitmax, ingest: true)
RAND_BITS.fetch(bitpow).each_slice(num_bits) { |bits|
bitset.set?(*bits)
}
}
end
if INCLUDE_BITSARRAY
b.report("BitsArray 2^#{bitpow} (#{bitmax} bits)") {
bitset = BitsArray.new(bitmax, ingest: true)
RAND_BITS.fetch(bitpow).each_slice(num_bits) { |bits|
bitset.set?(bits)
}
}
end
# using a pregenerated bitmap to compete with Bitset's approach
if INCLUDE_BITSAHLGOOD
b.report("BitSahlGood 2^#{bitpow} (#{bitmax} bits)") {
bitset = BSGS.fetch(bitpow)
RAND_BITS.fetch(bitpow).each_slice(num_bits) { |bits|
bitset.set?(bits)
}
}
end
b.compare!
}
puts
}
####
#### NOTE: YJIT ENABLED ON THE FIRST RUN
####
[rwh@nixos:~/code]$ RUBY_YJIT_ENABLE=1 ruby bitset_benchmark.rb
FINISHED PREGENERATION
========================================
2^6 (64) bits
========================================
ruby 3.2.2 (2023-03-30 revision e51014f9c0) +YJIT [x86_64-linux]
Warming up --------------------------------------
Bitset 2^6 (64 bits) 2.209k i/100ms
BitsInt 2^6 (64 bits)
983.000 i/100ms
BitsArray 2^6 (64 bits)
1.338k i/100ms
BitSahlGood 2^6 (64 bits)
1.000k i/100ms
Calculating -------------------------------------
Bitset 2^6 (64 bits) 21.385k (± 4.9%) i/s - 44.180k in 2.071445s
BitsInt 2^6 (64 bits)
9.171k (± 9.8%) i/s - 18.677k in 2.067093s
BitsArray 2^6 (64 bits)
11.967k (± 5.6%) i/s - 24.084k in 2.019460s
BitSahlGood 2^6 (64 bits)
9.195k (± 4.8%) i/s - 19.000k in 2.071547s
Comparison:
Bitset 2^6 (64 bits): 21384.9 i/s
BitsArray 2^6 (64 bits): 11966.8 i/s - 1.79x slower
BitSahlGood 2^6 (64 bits): 9194.8 i/s - 2.33x slower
BitsInt 2^6 (64 bits): 9170.7 i/s - 2.33x slower
========================================
2^8 (256) bits
========================================
ruby 3.2.2 (2023-03-30 revision e51014f9c0) +YJIT [x86_64-linux]
Warming up --------------------------------------
Bitset 2^8 (256 bits)
1.903k i/100ms
BitsInt 2^8 (256 bits)
840.000 i/100ms
BitsArray 2^8 (256 bits)
1.055k i/100ms
BitSahlGood 2^8 (256 bits)
958.000 i/100ms
Calculating -------------------------------------
Bitset 2^8 (256 bits)
21.325k (± 2.5%) i/s - 43.769k in 2.053726s
BitsInt 2^8 (256 bits)
9.743k (± 1.2%) i/s - 20.160k in 2.069533s
BitsArray 2^8 (256 bits)
11.436k (± 1.8%) i/s - 23.210k in 2.030256s
BitSahlGood 2^8 (256 bits)
10.044k (± 1.0%) i/s - 20.118k in 2.003231s
Comparison:
Bitset 2^8 (256 bits): 21325.4 i/s
BitsArray 2^8 (256 bits): 11436.0 i/s - 1.86x slower
BitSahlGood 2^8 (256 bits): 10043.7 i/s - 2.12x slower
BitsInt 2^8 (256 bits): 9742.8 i/s - 2.19x slower
========================================
2^10 (1024) bits
========================================
ruby 3.2.2 (2023-03-30 revision e51014f9c0) +YJIT [x86_64-linux]
Warming up --------------------------------------
Bitset 2^10 (1024 bits)
2.173k i/100ms
BitsInt 2^10 (1024 bits)
933.000 i/100ms
BitsArray 2^10 (1024 bits)
782.000 i/100ms
BitSahlGood 2^10 (1024 bits)
942.000 i/100ms
Calculating -------------------------------------
Bitset 2^10 (1024 bits)
21.630k (± 0.7%) i/s - 43.460k in 2.009307s
BitsInt 2^10 (1024 bits)
9.417k (± 0.6%) i/s - 19.593k in 2.080701s
BitsArray 2^10 (1024 bits)
7.838k (± 0.9%) i/s - 16.422k in 2.095352s
BitSahlGood 2^10 (1024 bits)
9.756k (± 0.6%) i/s - 19.782k in 2.027660s
Comparison:
Bitset 2^10 (1024 bits): 21630.4 i/s
BitSahlGood 2^10 (1024 bits): 9756.4 i/s - 2.22x slower
BitsInt 2^10 (1024 bits): 9416.9 i/s - 2.30x slower
BitsArray 2^10 (1024 bits): 7838.0 i/s - 2.76x slower
========================================
2^12 (4096) bits
========================================
ruby 3.2.2 (2023-03-30 revision e51014f9c0) +YJIT [x86_64-linux]
Warming up --------------------------------------
Bitset 2^12 (4096 bits)
2.184k i/100ms
BitsInt 2^12 (4096 bits)
907.000 i/100ms
BitsArray 2^12 (4096 bits)
344.000 i/100ms
BitSahlGood 2^12 (4096 bits)
966.000 i/100ms
Calculating -------------------------------------
Bitset 2^12 (4096 bits)
21.651k (± 0.5%) i/s - 43.680k in 2.017530s
BitsInt 2^12 (4096 bits)
9.127k (± 0.6%) i/s - 19.047k in 2.086938s
BitsArray 2^12 (4096 bits)
3.450k (± 1.5%) i/s - 7.224k in 2.094368s
BitSahlGood 2^12 (4096 bits)
10.053k (± 0.5%) i/s - 20.286k in 2.017930s
Comparison:
Bitset 2^12 (4096 bits): 21650.8 i/s
BitSahlGood 2^12 (4096 bits): 10053.2 i/s - 2.15x slower
BitsInt 2^12 (4096 bits): 9127.1 i/s - 2.37x slower
BitsArray 2^12 (4096 bits): 3450.0 i/s - 6.28x slower
========================================
2^14 (16384) bits
========================================
ruby 3.2.2 (2023-03-30 revision e51014f9c0) +YJIT [x86_64-linux]
Warming up --------------------------------------
Bitset 2^14 (16384 bits)
2.141k i/100ms
BitsInt 2^14 (16384 bits)
704.000 i/100ms
BitsArray 2^14 (16384 bits)
100.000 i/100ms
BitSahlGood 2^14 (16384 bits)
909.000 i/100ms
Calculating -------------------------------------
Bitset 2^14 (16384 bits)
21.466k (± 0.5%) i/s - 44.961k in 2.094549s
BitsInt 2^14 (16384 bits)
7.068k (± 0.9%) i/s - 14.784k in 2.091846s
BitsArray 2^14 (16384 bits)
1.076k (± 1.0%) i/s - 2.200k in 2.043995s
BitSahlGood 2^14 (16384 bits)
9.134k (± 1.2%) i/s - 19.089k in 2.090143s
Comparison:
Bitset 2^14 (16384 bits): 21466.2 i/s
BitSahlGood 2^14 (16384 bits): 9134.2 i/s - 2.35x slower
BitsInt 2^14 (16384 bits): 7068.1 i/s - 3.04x slower
BitsArray 2^14 (16384 bits): 1076.4 i/s - 19.94x slower
========================================
2^16 (65536) bits
========================================
ruby 3.2.2 (2023-03-30 revision e51014f9c0) +YJIT [x86_64-linux]
Warming up --------------------------------------
Bitset 2^16 (65536 bits)
2.140k i/100ms
BitsInt 2^16 (65536 bits)
395.000 i/100ms
BitsArray 2^16 (65536 bits)
26.000 i/100ms
BitSahlGood 2^16 (65536 bits)
911.000 i/100ms
Calculating -------------------------------------
Bitset 2^16 (65536 bits)
21.525k (± 0.4%) i/s - 44.940k in 2.087894s
BitsInt 2^16 (65536 bits)
3.930k (± 0.7%) i/s - 7.900k in 2.010234s
BitsArray 2^16 (65536 bits)
286.588 (± 1.7%) i/s - 598.000 in 2.087343s
BitSahlGood 2^16 (65536 bits)
9.300k (± 0.6%) i/s - 19.131k in 2.057146s
Comparison:
Bitset 2^16 (65536 bits): 21524.5 i/s
BitSahlGood 2^16 (65536 bits): 9300.2 i/s - 2.31x slower
BitsInt 2^16 (65536 bits): 3930.1 i/s - 5.48x slower
BitsArray 2^16 (65536 bits): 286.6 i/s - 75.11x slower
========================================
2^18 (262144) bits
========================================
ruby 3.2.2 (2023-03-30 revision e51014f9c0) +YJIT [x86_64-linux]
Warming up --------------------------------------
Bitset 2^18 (262144 bits)
2.167k i/100ms
BitsInt 2^18 (262144 bits)
107.000 i/100ms
BitsArray 2^18 (262144 bits)
6.000 i/100ms
BitSahlGood 2^18 (262144 bits)
944.000 i/100ms
Calculating -------------------------------------
Bitset 2^18 (262144 bits)
21.439k (± 0.4%) i/s - 43.340k in 2.021540s
BitsInt 2^18 (262144 bits)
1.216k (± 0.4%) i/s - 2.461k in 2.024009s
BitsArray 2^18 (262144 bits)
70.434 (± 2.8%) i/s - 144.000 in 2.046804s
BitSahlGood 2^18 (262144 bits)
9.648k (± 0.4%) i/s - 19.824k in 2.054840s
Comparison:
Bitset 2^18 (262144 bits): 21439.4 i/s
BitSahlGood 2^18 (262144 bits): 9647.6 i/s - 2.22x slower
BitsInt 2^18 (262144 bits): 1215.9 i/s - 17.63x slower
BitsArray 2^18 (262144 bits): 70.4 i/s - 304.39x slower
========================================
2^20 (1048576) bits
========================================
ruby 3.2.2 (2023-03-30 revision e51014f9c0) +YJIT [x86_64-linux]
Warming up --------------------------------------
Bitset 2^20 (1048576 bits)
2.151k i/100ms
BitsInt 2^20 (1048576 bits)
24.000 i/100ms
BitsArray 2^20 (1048576 bits)
1.000 i/100ms
BitSahlGood 2^20 (1048576 bits)
1.010k i/100ms
Calculating -------------------------------------
Bitset 2^20 (1048576 bits)
21.412k (± 0.5%) i/s - 43.020k in 2.009180s
BitsInt 2^20 (1048576 bits)
270.291 (± 0.7%) i/s - 552.000 in 2.042408s
BitsArray 2^20 (1048576 bits)
17.431 (± 5.7%) i/s - 35.000 in 2.011533s
BitSahlGood 2^20 (1048576 bits)
10.140k (± 0.6%) i/s - 21.210k in 2.091707s
Comparison:
Bitset 2^20 (1048576 bits): 21412.2 i/s
BitSahlGood 2^20 (1048576 bits): 10140.4 i/s - 2.11x slower
BitsInt 2^20 (1048576 bits): 270.3 i/s - 79.22x slower
BitsArray 2^20 (1048576 bits): 17.4 i/s - 1228.42x slower
####
#### YJIT DISABLED BELOW ####
####
[rwh@nixos:~/code]$ ruby bitset_benchmark.rb
FINISHED PREGENERATION
========================================
2^6 (64) bits
========================================
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux]
Warming up --------------------------------------
Bitset 2^6 (64 bits) 2.247k i/100ms
BitsInt 2^6 (64 bits)
1.000k i/100ms
BitsArray 2^6 (64 bits)
1.307k i/100ms
BitSahlGood 2^6 (64 bits)
952.000 i/100ms
Calculating -------------------------------------
Bitset 2^6 (64 bits) 22.310k (± 0.9%) i/s - 44.940k in 2.014533s
BitsInt 2^6 (64 bits)
10.331k (± 0.4%) i/s - 21.000k in 2.032664s
BitsArray 2^6 (64 bits)
12.975k (± 0.6%) i/s - 26.140k in 2.014676s
BitSahlGood 2^6 (64 bits)
8.624k (±13.5%) i/s - 17.136k in 2.032006s
Comparison:
Bitset 2^6 (64 bits): 22309.6 i/s
BitsArray 2^6 (64 bits): 12975.3 i/s - 1.72x slower
BitsInt 2^6 (64 bits): 10331.4 i/s - 2.16x slower
BitSahlGood 2^6 (64 bits): 8624.3 i/s - 2.59x slower
========================================
2^8 (256) bits
========================================
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux]
Warming up --------------------------------------
Bitset 2^8 (256 bits)
2.132k i/100ms
BitsInt 2^8 (256 bits)
918.000 i/100ms
BitsArray 2^8 (256 bits)
1.004k i/100ms
BitSahlGood 2^8 (256 bits)
879.000 i/100ms
Calculating -------------------------------------
Bitset 2^8 (256 bits)
20.147k (± 6.0%) i/s - 40.508k in 2.018872s
BitsInt 2^8 (256 bits)
9.127k (± 2.7%) i/s - 18.360k in 2.013033s
BitsArray 2^8 (256 bits)
10.114k (± 3.3%) i/s - 21.084k in 2.087031s
BitSahlGood 2^8 (256 bits)
8.650k (± 6.9%) i/s - 17.580k in 2.043493s
Comparison:
Bitset 2^8 (256 bits): 20146.5 i/s
BitsArray 2^8 (256 bits): 10113.9 i/s - 1.99x slower
BitsInt 2^8 (256 bits): 9127.4 i/s - 2.21x slower
BitSahlGood 2^8 (256 bits): 8650.0 i/s - 2.33x slower
========================================
2^10 (1024) bits
========================================
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux]
Warming up --------------------------------------
Bitset 2^10 (1024 bits)
1.877k i/100ms
BitsInt 2^10 (1024 bits)
978.000 i/100ms
BitsArray 2^10 (1024 bits)
684.000 i/100ms
BitSahlGood 2^10 (1024 bits)
922.000 i/100ms
Calculating -------------------------------------
Bitset 2^10 (1024 bits)
21.393k (± 2.5%) i/s - 43.171k in 2.019329s
BitsInt 2^10 (1024 bits)
9.422k (± 1.8%) i/s - 19.560k in 2.076699s
BitsArray 2^10 (1024 bits)
6.751k (± 1.5%) i/s - 13.680k in 2.026925s
BitSahlGood 2^10 (1024 bits)
8.801k (± 9.1%) i/s - 17.518k in 2.013743s
Comparison:
Bitset 2^10 (1024 bits): 21392.8 i/s
BitsInt 2^10 (1024 bits): 9422.0 i/s - 2.27x slower
BitSahlGood 2^10 (1024 bits): 8800.7 i/s - 2.43x slower
BitsArray 2^10 (1024 bits): 6750.6 i/s - 3.17x slower
========================================
2^12 (4096) bits
========================================
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux]
Warming up --------------------------------------
Bitset 2^12 (4096 bits)
2.025k i/100ms
BitsInt 2^12 (4096 bits)
790.000 i/100ms
BitsArray 2^12 (4096 bits)
274.000 i/100ms
BitSahlGood 2^12 (4096 bits)
766.000 i/100ms
Calculating -------------------------------------
Bitset 2^12 (4096 bits)
21.515k (± 2.4%) i/s - 44.550k in 2.071841s
BitsInt 2^12 (4096 bits)
8.932k (± 1.0%) i/s - 18.170k in 2.034556s
BitsArray 2^12 (4096 bits)
2.880k (± 0.7%) i/s - 6.028k in 2.093146s
BitSahlGood 2^12 (4096 bits)
8.644k (± 8.8%) i/s - 17.618k in 2.059658s
Comparison:
Bitset 2^12 (4096 bits): 21514.6 i/s
BitsInt 2^12 (4096 bits): 8931.7 i/s - 2.41x slower
BitSahlGood 2^12 (4096 bits): 8644.5 i/s - 2.49x slower
BitsArray 2^12 (4096 bits): 2880.0 i/s - 7.47x slower
========================================
2^14 (16384) bits
========================================
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux]
Warming up --------------------------------------
Bitset 2^14 (16384 bits)
2.215k i/100ms
BitsInt 2^14 (16384 bits)
723.000 i/100ms
BitsArray 2^14 (16384 bits)
82.000 i/100ms
BitSahlGood 2^14 (16384 bits)
816.000 i/100ms
Calculating -------------------------------------
Bitset 2^14 (16384 bits)
21.097k (± 2.2%) i/s - 44.300k in 2.100936s
BitsInt 2^14 (16384 bits)
6.981k (± 1.9%) i/s - 14.460k in 2.071997s
BitsArray 2^14 (16384 bits)
834.144 (± 1.4%) i/s - 1.722k in 2.064812s
BitSahlGood 2^14 (16384 bits)
8.281k (± 1.8%) i/s - 17.136k in 2.070040s
Comparison:
Bitset 2^14 (16384 bits): 21096.6 i/s
BitSahlGood 2^14 (16384 bits): 8280.8 i/s - 2.55x slower
BitsInt 2^14 (16384 bits): 6981.3 i/s - 3.02x slower
BitsArray 2^14 (16384 bits): 834.1 i/s - 25.29x slower
========================================
2^16 (65536) bits
========================================
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux]
Warming up --------------------------------------
Bitset 2^16 (65536 bits)
2.172k i/100ms
BitsInt 2^16 (65536 bits)
381.000 i/100ms
BitsArray 2^16 (65536 bits)
20.000 i/100ms
BitSahlGood 2^16 (65536 bits)
900.000 i/100ms
Calculating -------------------------------------
Bitset 2^16 (65536 bits)
21.372k (± 2.3%) i/s - 43.440k in 2.033591s
BitsInt 2^16 (65536 bits)
4.101k (± 1.0%) i/s - 8.382k in 2.044167s
BitsArray 2^16 (65536 bits)
225.633 (± 1.8%) i/s - 460.000 in 2.039237s
BitSahlGood 2^16 (65536 bits)
8.220k (± 9.5%) i/s - 17.100k in 2.098245s
Comparison:
Bitset 2^16 (65536 bits): 21372.2 i/s
BitSahlGood 2^16 (65536 bits): 8220.3 i/s - 2.60x slower
BitsInt 2^16 (65536 bits): 4100.8 i/s - 5.21x slower
BitsArray 2^16 (65536 bits): 225.6 i/s - 94.72x slower
========================================
2^18 (262144) bits
========================================
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux]
Warming up --------------------------------------
Bitset 2^18 (262144 bits)
1.833k i/100ms
BitsInt 2^18 (262144 bits)
91.000 i/100ms
BitsArray 2^18 (262144 bits)
4.000 i/100ms
BitSahlGood 2^18 (262144 bits)
946.000 i/100ms
Calculating -------------------------------------
Bitset 2^18 (262144 bits)
18.514k (± 6.4%) i/s - 38.493k in 2.086500s
BitsInt 2^18 (262144 bits)
1.083k (± 7.1%) i/s - 2.184k in 2.027616s
BitsArray 2^18 (262144 bits)
50.682 (± 5.9%) i/s - 104.000 in 2.059415s
BitSahlGood 2^18 (262144 bits)
8.444k (± 9.7%) i/s - 17.028k in 2.034445s
Comparison:
Bitset 2^18 (262144 bits): 18514.2 i/s
BitSahlGood 2^18 (262144 bits): 8443.7 i/s - 2.19x slower
BitsInt 2^18 (262144 bits): 1082.5 i/s - 17.10x slower
BitsArray 2^18 (262144 bits): 50.7 i/s - 365.30x slower
========================================
2^20 (1048576) bits
========================================
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux]
Warming up --------------------------------------
Bitset 2^20 (1048576 bits)
2.192k i/100ms
BitsInt 2^20 (1048576 bits)
24.000 i/100ms
BitsArray 2^20 (1048576 bits)
1.000 i/100ms
BitSahlGood 2^20 (1048576 bits)
928.000 i/100ms
Calculating -------------------------------------
Bitset 2^20 (1048576 bits)
21.870k (± 0.7%) i/s - 43.840k in 2.004678s
BitsInt 2^20 (1048576 bits)
272.951 (± 2.9%) i/s - 552.000 in 2.024049s
BitsArray 2^20 (1048576 bits)
14.222 (± 7.0%) i/s - 29.000 in 2.042680s
BitSahlGood 2^20 (1048576 bits)
9.477k (± 0.5%) i/s - 19.488k in 2.056429s
Comparison:
Bitset 2^20 (1048576 bits): 21870.1 i/s
BitSahlGood 2^20 (1048576 bits): 9476.9 i/s - 2.31x slower
BitsInt 2^20 (1048576 bits): 273.0 i/s - 80.12x slower
BitsArray 2^20 (1048576 bits): 14.2 i/s - 1537.78x slower
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment