Skip to content

Instantly share code, notes, and snippets.

@marcandre
Last active December 31, 2020 21:36
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 marcandre/bfed626e538a3d0fc7cad38dc026cf0e to your computer and use it in GitHub Desktop.
Save marcandre/bfed626e538a3d0fc7cad38dc026cf0e to your computer and use it in GitHub Desktop.
Ractor benchmark
#!/usr/bin/env ruby
if ENV['B']
BuiltinRactor = Ractor
Object.send :remove_const, :Ractor
require 'backports/3.0.0/ractor'
puts "Using pure Ruby implementation"
end
# usage `ruby ractor_test.rb <work_length> <num_workers> <num_requests>
WORK_LENGTH = (ARGV[0] || 10_000).to_i
NUM_WORKERS = (ARGV[1] || 8).to_i
WORK_LOAD = 1_000_000
NUM_REQUESTS = (ARGV[2] || (WORK_LOAD / WORK_LENGTH / NUM_WORKERS) ).to_i
CPU = WORK_LENGTH * 4
def cpu_work(_n)
CPU.times.inject(:+)
end
def fib(i)
return 1 if i <= 1
fib(i-2) + fib(i-1)
end
def fib_work(_n)
fib(Math.log(WORK_LENGTH).to_i + 15)
end
def sleep_work(n)
sleep(0.00001 * WORK_LENGTH) if n % 10 == 0
end
r = %i[fib cpu sleep].to_h do |type|
eval "alias work #{type}_work"
t0 = Time.now
pipe = Ractor.new do
loop do
Ractor.yield Ractor.receive
end
close_outgoing # don't send `nil`
end
NUM_WORKERS.times.map do
Ractor.new(pipe, Ractor.main) do |from, to|
loop do
n = from.take
to.send work(n), move: true
end
end
end
(NUM_REQUESTS*NUM_WORKERS).times do |i|
pipe << i
end
pipe.close_incoming
(NUM_REQUESTS*NUM_WORKERS).times do
Ractor.receive
end
t1 = Time.now
delay = ((t1 - t0) * 1000).to_i
[type, delay]
end
puts r.map { |type, delay|
"#{type}: #{delay} ms"
}.join(' | ')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment