stdlib's 'benchmark' is not good, at least, for every use case I've ever had for benchmarking.
So here's some hacking I did tonight.
db = Sequel.sqlite("/tmp/example.db")
db.run("CREATE TABLE foo (i INTEGER)")
Stud::Benchmark.run(5000) { db[:foo].insert(1) }
rvm 1.9.3 do ruby -rsequel -r./benchmark.rb -e 'db = Sequel.sqlite("/tmp/example.db"); db.run("CREATE TABLE foo (i INTEGER)"); r = Stud::Benchmark.run(5000) { db[:foo].insert(1) }; puts r; r.pretty_print'
ruby 1.9.3: avg: 0.014027055783200017 stddev: 0.007770915686125679
0.0078125...0.015625: ███████████████████████████████████████████████
0.015625...0.03125: ███
0.03125...0.0625: █
0.0625...0.125: █
0.125...0.25: █
0.25...0.5: █
Running in virtualbox on a workstation with an SSD. 14ms average time spent writing one row? that seems crazy.
Running individually to verify:
>> r = Stud::Benchmark.run(1) { db[:foo].insert(1) }
=> ruby 1.9.3: avg: 0.015876558 stddev: NaN
>> r = Stud::Benchmark.run(1) { db[:foo].insert(1) }
=> ruby 1.9.3: avg: 0.015174503 stddev: NaN
>> r = Stud::Benchmark.run(1) { db[:foo].insert(1) }
=> ruby 1.9.3: avg: 0.034166633 stddev: NaN
# Now without benchmark, to verify.
>> start = Time.now; db[:foo].insert(1); Time.now - start
=> 0.01603736
>> start = Time.now; db[:foo].insert(1); Time.now - start
=> 0.016474039
>> start = Time.now; db[:foo].insert(1); Time.now - start
=> 0.013570604
Crazy slow! Still, a good show of where I'm going with this tool :)
Stud::Benchmark.run(50) { TCPSocket.new("semicomplete.com", 80).close };
% rvm 1.9.3 do ruby -rsocket -r./benchmark.rb -e 'r = Stud::Benchmark.run(50) { TCPSocket.new("semicomplete.com", 80).close }; puts r; r.pretty_print'
ruby 1.9.3: avg: 0.07132824932 stddev: 0.020798285116304303
0.0625...0.125: ████████████████████████████████████████████████
0.125...0.25: ██
This next tcp example uses two different hostnames, chosen at random, to highlight latency bands:
>> hosts = [ "www.google.com", "semicomplete.com" ]
=> ["www.google.com", "semicomplete.com"]
>> r = Stud::Benchmark.run(100) { TCPSocket.new(hosts.shuffle.first, 80).close }
=> ruby 1.9.3: avg: 0.057115173200000015 stddev: 0.10279068316129422
>> r.pretty_print
0.015625...0.03125: ██████████████████████
0.03125...0.0625: ████
0.0625...0.125: ████████████████████████
0.25...0.5: █
1.0...2.0: █
Note the two large groups in the 15-30ms and 62-125ms ranges.
Stud::Benchmark.run(50) { Net::HTTP.get("grokhint.herokuapp.com", "/") }
ruby 1.9.3: avg: 0.35898339220000003 stddev: 0.7865973102824785
0.125...0.25: ███████████████████████████████
0.25...0.5: ██████████████████
4.0...8.0: █