#!/usr/bin/env ruby # frozen_string_literal: true # Released under the MIT License. # Copyright, 2018-2022, by Samuel Williams. require 'async' require 'lightio' require 'benchmark/ips' # # It's hard to know exactly how to interpret these results. When running parallel # instances, resource contention is more likely to be a problem, and yet with # async, the performance between a single task and several tasks is roughly the # same, while in the case of lightio, there is an obvious performance gap. # # The main takeaway is that contention causes issues and if systems are not # designed with that in mind, it will impact performance. # # $ ruby async_vs_lightio.rb # Warming up -------------------------------------- # lightio (synchronous) # 2.439k i/100ms # async (synchronous) 2.115k i/100ms # lightio (parallel) 211.000 i/100ms # async (parallel) 449.000 i/100ms # Calculating ------------------------------------- # lightio (synchronous) # 64.502k (± 3.9%) i/s - 643.896k in 10.002151s # async (synchronous) 161.195k (± 1.6%) i/s - 1.612M in 10.000976s # lightio (parallel) 49.827k (±17.5%) i/s - 477.704k in 9.999579s # async (parallel) 166.862k (± 6.2%) i/s - 1.662M in 10.000365s # # Comparison: # async (parallel): 166862.3 i/s # async (synchronous): 161194.6 i/s - same-ish: difference falls within error # lightio (synchronous): 64502.5 i/s - 2.59x slower # lightio (parallel): 49827.3 i/s - 3.35x slower DURATION = 0.000001 def run_async(count, repeats = 10000) Async::Reactor.run do |task| count.times.map do task.async do |subtask| repeats.times do subtask.sleep(DURATION) end end end.each(&:wait) end end def run_lightio(count, repeats = 10000) count.times.map do LightIO::Beam.new do repeats.times do LightIO.sleep(DURATION) end end end.each(&:join) end Benchmark.ips do |benchmark| benchmark.time = 10 benchmark.warmup = 2 benchmark.report("lightio (synchronous)") do |count| run_lightio(1, count) end benchmark.report("async (synchronous)") do |count| run_async(1, count) end benchmark.report("lightio (parallel)") do |count| run_lightio(32, count/32) end benchmark.report("async (parallel)") do |count| run_async(32, count/32) end benchmark.compare! end