Inspired by https://gist.github.com/havenwood/4724778.
# for topaz
class String
def _rjust(x,c=" ")
return self if (self.length > x);
return c*(x-self.length) + self;
end
def _ljust(x,c=" ")
return self if (self.length > x);
return self + c*(x-self.length);
end
end
class Numeric
def _floor(x)
return (((self*(10**x)).to_i()).to_f())/((10**x).to_f());
end
def _p()
return (self._floor(6).to_s())._ljust(8,"0")._rjust(9);
end
end
$lcg_seed = 723;
def _srand(seed)
$lcg_seed = seed;
end
def _rand()
$lcg_seed = (($lcg_seed*1103515245)&2147483647)+12345;
return $lcg_seed & 2147483647;
end
def benchmark(title, &block)
a = [];
5.times {
t = Time.now;
block.call;
a << Time.now - t;
}
average = a.inject(0) { |s,x| s+x }/a.size.to_f();
variance = a.inject(0) { |s,x| s+(x-average)**2 }/(a.size-1).to_f();
df = 2.7764;
mi = df * Math.sqrt(variance / (a.size-1));
puts(title._rjust(15) + ": #{average._p} #{(average-mi)._p} - #{(average+mi)._p}");
end
puts(" "*17 + "average"._rjust(9) + " " + "95%-lwr"._rjust(9) + " " + "95%-upr"._rjust(9));
# ensure timer works well
benchmark("sleep200ms") { sleep(0.2); }
# random
benchmark("lcgrand") {
_srand(72300);
10000000.times { _rand(); }
}
#
# sort
_srand(723);
unsorted = (0...1000000).map { _rand(); };
benchmark("sort") {
sorted = unsorted.sort();
}
# fib
def fib(n)
return n<2 ? n:(fib(n-2)+fib(n-1));
end
benchmark("fibonacci") { fib(35); }
benchmark("eratosthen-ish") {
a = (0..2500000).to_a();
l = a.last;
(a.first...a.last).each { |i|
a[i] = nil if (i<2);
next if (!a[i]);
(i+i).step(l,i) { |x| a[x] = nil; }
}
# a.compact!();
}
# strcat
benchmark("strcat") {
s = "";
5000000.times { |i| s << "unko"; };
}
# gsub
benchmark("gsub") {
s = "unko"*10000000;
s.gsub("ko","nchi");
}
benchmark("regexp") {
r = /http:\/\/[\-\.\/a-zA-Z0-9:\@&=+\$,%#]/;
s = "unko"*100000 + "http://lpm11.net/" + "unko"*100000;
1000.times { r =~ s; };
}
-
10 faster: lcgrand, strcat
-
5 faster: gsub
-
2 faster: fibonacci, eratosthen-ish
- slower: regexp, sort
Note: Following time is result at rubbish machine, so result may varies (Sexy prime benchmark takes 309.95 sec at MRI, 19.09 sec at Topaz).
average 95%-lwr 95%-upr
sleep200ms: 0.200383 0.200336 - 0.200430
lcgrand: 0.137908 0.126807 - 0.149009
sort: 5.499931 5.308957 - 5.690904
fibonacci: 4.449075 3.482507 - 5.415642
eratosthen-ish: 2.769728 2.198354 - 3.341102
strcat: 0.529514 0.449336 - 0.609693
gsub: 2.555540 2.464100 - 2.646981
regexp: 2.461864 2.413191 - 2.510536
average 95%-lwr 95%-upr
sleep200ms: 0.200188 0.200113 - 0.200264
lcgrand: 11.569965 11.316432 - 11.823498
sort: 0.825600 0.731737 - 0.919462
fibonacci: 10.994121 10.90808 - 11.080162
eratosthen-ish: 6.989114 6.949861 - 7.028367
strcat: 9.130288 9.066262 - 9.194313
gsub: 12.623258 11.82916 - 13.417356
regexp: 0.706247 0.681439 - 0.731056
- Topaz currently not supports String#rjust, Numeric#floor ? :P
- Crystal (https://github.com/manastech/crystal) may even faster, but seems to not support block argument, so didn't tried.
Syntax error in /home/lpm11/warabench.rb:36: expecting token 'IDENT', not '&'
def benchmark(title, &block)
Yes, Crystal doesn't support block arguments yet, but you can use "yield", no need to use the &block argument in your case.
But, anyway, Crystal still misses a lot of the functionality found in Ruby's std, like the Time class. But your benchmarks look very interesting, we'll try to make them work as soon as possible in Crystal and we'll let you know the times. :-)