Skip to content

Instantly share code, notes, and snippets.

@cdimartino
Created April 16, 2024 18:16
Show Gist options
  • Save cdimartino/89310b3855c1a5e4c7f38214c61dd2a3 to your computer and use it in GitHub Desktop.
Save cdimartino/89310b3855c1a5e4c7f38214c61dd2a3 to your computer and use it in GitHub Desktop.
Benchmark manual Mutex vs Concurrent::Array
require "benchmark"
require "concurrent-ruby"
class Bench
def initialize(arrayish)
@arrayish = arrayish
end
def self.run
count = 100
Benchmark.bmbm do |x|
x.report("concurrent: #{count} threads") do
threads = count.times.map do |i|
Thread.new do
Thread.current.name = "concurrent #{i}"
arrayish = Concurrent::Array.new
bench = Bench.new(arrayish)
bench.run
end
end
threads.each(&:join)
end
x.report("mutex: #{count} threads") do
threads = count.times.map do |i|
Thread.new do
Thread.current.name = "mutex #{i}"
arrayish = MutexArray.new
bench = Bench.new(arrayish)
bench.run
end
end
threads.each(&:join)
end
end
end
def run
out = []
100.times do
100.times { @arrayish.push(rand(0..100)) }
out << @arrayish.zip(100.times.map { rand(1..100) })
out << 42.times { @arrayish.pop }
out << @arrayish.length
out << @arrayish.empty?
out << @arrayish.map { |i| next(i) }
end
out
end
def next(i) = i.next
end
class MutexArray
def initialize
@array = []
@mutex = Mutex.new
end
def push(value)
@mutex.synchronize do
@array.push(value)
end
end
def pop
@mutex.synchronize do
@array.pop
end
end
def length
@mutex.synchronize do
@array.length
end
end
def empty?
@mutex.synchronize do
@array.empty?
end
end
def each(&block)
@mutex.synchronize do
@array.each(&block)
end
end
def map(&block)
@mutex.synchronize do
@array.map(&block)
end
end
def zip(other)
@mutex.synchronize do
@array.zip(other)
end
end
end
Bench.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment