Skip to content

⚡️ Improve SequenceSet#xor performance by ~2x #463

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ gem "test-unit"
gem "test-unit-ruby-core", git: "https://github.com/ruby/test-unit-ruby-core"

gem "benchmark-driver", require: false
gem "benchmark-ips", require: false

group :test do
gem "simplecov", require: false
Expand Down
36 changes: 36 additions & 0 deletions benchmarks/seqset-ops.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env ruby
require "benchmark/ips"
require "net/imap"

warmup = 1.0
time = 5.0
size_a = 10_000
size_b = 10_000
max_a = 14_000
max_b = 14_000

SeqSet = Net::IMAP::SequenceSet
a = SeqSet[Array.new(size_a) { rand(1..max_a) }]
b = SeqSet[Array.new(size_b) { rand(1..max_b) }]

puts ?=*72
puts "SequenceSet XOR implementations"
Benchmark.ips do |x|
x.config(warmup:, time:)

# the original was missing the "a.dup", so it crashed or mutated a!
x.report("a ^ b") do a.dup ^ b end
x.report("new (a - b) | (b - a)") do
SeqSet.new(a).subtract(b).merge(SeqSet.new(b).subtract(a))
end
x.report("dup (a - b) | (b - a)") do
a.dup.subtract(b).merge(b.dup.subtract(a))
end
x.report("(a.dup | b).subtract(a & b)") do (a.dup | b).subtract(a & b) end
x.report("dup (a | b) - (a & b)") do a.dup.merge(b).subtract(a & b) end

x.report("(a - b) | (b - a)") do (a - b) | (b - a) end
x.report("(a | b) - (a & b)") do (a | b) - (a & b) end

x.compare!
end
4 changes: 3 additions & 1 deletion lib/net/imap/sequence_set.rb
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,9 @@ def &(other)
#
# <tt>(seqset ^ other)</tt> is equivalent to <tt>((seqset | other) -
# (seqset & other))</tt>.
def ^(other) remain_frozen (dup | other).subtract(self & other) end
def ^(other)
remain_frozen dup.subtract(SequenceSet.new(other).subtract(self))
end
alias xor :^

# :call-seq:
Expand Down
Loading