1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Revert "benchmark/*.yml: convert from benchmark/bm_*.rb"

This reverts r63900.

Having single-execution benchmark as a normal Ruby script is preferred
by ko1. I'm not a big fan of having inconsistent benchmark formats, but
I can understand some benefits of it.

common.mk: remove obsolsted benchmark-each PHONY declaration, support
running Ruby scripts added by this commit.

README.md: follow ARGS change

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63926 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
k0kubun 2018-07-10 13:05:29 +00:00
parent bd12037e50
commit 8068d34cfe
256 changed files with 3075 additions and 3467 deletions

View file

@ -37,8 +37,8 @@ make benchmark ITEM=vm1
# Run some limited benchmarks in ITEM-matched files
make benchmark ITEM=vm1 OPTS=--filter=block
# You can specify the benchmark by an exact filename instead of using
# the default argument: ARGS=$(srcdir)/benchmark/*$(ITEM)*.yml
# You can specify the benchmark by an exact filename instead of using the default argument:
# ARGS = $$(find $(srcdir)/benchmark -maxdepth 1 -name '*$(ITEM)*.yml' -o -name '*$(ITEM)*.rb')
make benchmark ARGS=../benchmark/erb_render.yml
# You can specify any option via $OPTS

View file

@ -1,18 +0,0 @@
benchmark:
app_answer: |
def ack(m, n)
if m == 0 then
n + 1
elsif n == 0 then
ack(m - 1, 1)
else
ack(m - 1, ack(m, n - 1))
end
end
def the_answer_to_life_the_universe_and_everything
(ack(3,7).to_s.split(//).inject(0){|s,x| s+x.to_i}.to_s + "2" ).to_i
end
answer = the_answer_to_life_the_universe_and_everything
loop_count: 1

View file

@ -1,295 +0,0 @@
prelude: |
# AO render benchmark
# Original program (C) Syoyo Fujita in Javascript (and other languages)
# https://code.google.com/p/aobench/
# Ruby(yarv2llvm) version by Hideki Miura
benchmark:
app_aobench: |
#
IMAGE_WIDTH = 256
IMAGE_HEIGHT = 256
NSUBSAMPLES = 2
NAO_SAMPLES = 8
class Vec
def initialize(x, y, z)
@x = x
@y = y
@z = z
end
attr_accessor :x, :y, :z
def vadd(b)
Vec.new(@x + b.x, @y + b.y, @z + b.z)
end
def vsub(b)
Vec.new(@x - b.x, @y - b.y, @z - b.z)
end
def vcross(b)
Vec.new(@y * b.z - @z * b.y,
@z * b.x - @x * b.z,
@x * b.y - @y * b.x)
end
def vdot(b)
@x * b.x + @y * b.y + @z * b.z
end
def vlength
Math.sqrt(@x * @x + @y * @y + @z * @z)
end
def vnormalize
len = vlength
v = Vec.new(@x, @y, @z)
if len > 1.0e-17 then
v.x = v.x / len
v.y = v.y / len
v.z = v.z / len
end
v
end
end
class Sphere
def initialize(center, radius)
@center = center
@radius = radius
end
attr_reader :center, :radius
def intersect(ray, isect)
rs = ray.org.vsub(@center)
b = rs.vdot(ray.dir)
c = rs.vdot(rs) - (@radius * @radius)
d = b * b - c
if d > 0.0 then
t = - b - Math.sqrt(d)
if t > 0.0 and t < isect.t then
isect.t = t
isect.hit = true
isect.pl = Vec.new(ray.org.x + ray.dir.x * t,
ray.org.y + ray.dir.y * t,
ray.org.z + ray.dir.z * t)
n = isect.pl.vsub(@center)
isect.n = n.vnormalize
else
0.0
end
end
nil
end
end
class Plane
def initialize(p, n)
@p = p
@n = n
end
def intersect(ray, isect)
d = -@p.vdot(@n)
v = ray.dir.vdot(@n)
v0 = v
if v < 0.0 then
v0 = -v
end
if v0 < 1.0e-17 then
return
end
t = -(ray.org.vdot(@n) + d) / v
if t > 0.0 and t < isect.t then
isect.hit = true
isect.t = t
isect.n = @n
isect.pl = Vec.new(ray.org.x + t * ray.dir.x,
ray.org.y + t * ray.dir.y,
ray.org.z + t * ray.dir.z)
end
nil
end
end
class Ray
def initialize(org, dir)
@org = org
@dir = dir
end
attr_accessor :org, :dir
end
class Isect
def initialize
@t = 10000000.0
@hit = false
@pl = Vec.new(0.0, 0.0, 0.0)
@n = Vec.new(0.0, 0.0, 0.0)
end
attr_accessor :t, :hit, :pl, :n
end
def clamp(f)
i = f * 255.5
if i > 255.0 then
i = 255.0
end
if i < 0.0 then
i = 0.0
end
i.to_i
end
def otherBasis(basis, n)
basis[2] = Vec.new(n.x, n.y, n.z)
basis[1] = Vec.new(0.0, 0.0, 0.0)
if n.x < 0.6 and n.x > -0.6 then
basis[1].x = 1.0
elsif n.y < 0.6 and n.y > -0.6 then
basis[1].y = 1.0
elsif n.z < 0.6 and n.z > -0.6 then
basis[1].z = 1.0
else
basis[1].x = 1.0
end
basis[0] = basis[1].vcross(basis[2])
basis[0] = basis[0].vnormalize
basis[1] = basis[2].vcross(basis[0])
basis[1] = basis[1].vnormalize
end
class Scene
def initialize
@spheres = Array.new
@spheres[0] = Sphere.new(Vec.new(-2.0, 0.0, -3.5), 0.5)
@spheres[1] = Sphere.new(Vec.new(-0.5, 0.0, -3.0), 0.5)
@spheres[2] = Sphere.new(Vec.new(1.0, 0.0, -2.2), 0.5)
@plane = Plane.new(Vec.new(0.0, -0.5, 0.0), Vec.new(0.0, 1.0, 0.0))
end
def ambient_occlusion(isect)
basis = Array.new
otherBasis(basis, isect.n)
ntheta = NAO_SAMPLES
nphi = NAO_SAMPLES
eps = 0.0001
occlusion = 0.0
p0 = Vec.new(isect.pl.x + eps * isect.n.x,
isect.pl.y + eps * isect.n.y,
isect.pl.z + eps * isect.n.z)
nphi.times do |j|
ntheta.times do |i|
r = rand
phi = 2.0 * 3.14159265 * rand
x = Math.cos(phi) * Math.sqrt(1.0 - r)
y = Math.sin(phi) * Math.sqrt(1.0 - r)
z = Math.sqrt(r)
rx = x * basis[0].x + y * basis[1].x + z * basis[2].x
ry = x * basis[0].y + y * basis[1].y + z * basis[2].y
rz = x * basis[0].z + y * basis[1].z + z * basis[2].z
raydir = Vec.new(rx, ry, rz)
ray = Ray.new(p0, raydir)
occisect = Isect.new
@spheres[0].intersect(ray, occisect)
@spheres[1].intersect(ray, occisect)
@spheres[2].intersect(ray, occisect)
@plane.intersect(ray, occisect)
if occisect.hit then
occlusion = occlusion + 1.0
else
0.0
end
end
end
occlusion = (ntheta.to_f * nphi.to_f - occlusion) / (ntheta.to_f * nphi.to_f)
Vec.new(occlusion, occlusion, occlusion)
end
def render(w, h, nsubsamples)
cnt = 0
nsf = nsubsamples.to_f
h.times do |y|
w.times do |x|
rad = Vec.new(0.0, 0.0, 0.0)
# Subsampling
nsubsamples.times do |v|
nsubsamples.times do |u|
cnt = cnt + 1
wf = w.to_f
hf = h.to_f
xf = x.to_f
yf = y.to_f
uf = u.to_f
vf = v.to_f
px = (xf + (uf / nsf) - (wf / 2.0)) / (wf / 2.0)
py = -(yf + (vf / nsf) - (hf / 2.0)) / (hf / 2.0)
eye = Vec.new(px, py, -1.0).vnormalize
ray = Ray.new(Vec.new(0.0, 0.0, 0.0), eye)
isect = Isect.new
@spheres[0].intersect(ray, isect)
@spheres[1].intersect(ray, isect)
@spheres[2].intersect(ray, isect)
@plane.intersect(ray, isect)
if isect.hit then
col = ambient_occlusion(isect)
rad.x = rad.x + col.x
rad.y = rad.y + col.y
rad.z = rad.z + col.z
end
end
end
r = rad.x / (nsf * nsf)
g = rad.y / (nsf * nsf)
b = rad.z / (nsf * nsf)
printf("%c", clamp(r))
printf("%c", clamp(g))
printf("%c", clamp(b))
end
nil
end
nil
end
end
alias printf_orig printf
def printf *args
end
# File.open("ao.ppm", "w") do |fp|
printf("P6\n")
printf("%d %d\n", IMAGE_WIDTH, IMAGE_HEIGHT)
printf("255\n", IMAGE_WIDTH, IMAGE_HEIGHT)
Scene.new.render(IMAGE_WIDTH, IMAGE_HEIGHT, NSUBSAMPLES)
# end
undef printf
alias printf printf_orig
loop_count: 1

View file

@ -1,28 +0,0 @@
benchmark:
app_erb: |
#
# Create many HTML strings with ERB.
#
require 'erb'
data = <<erb
<html>
<head> <%= title %> </head>
<body>
<h1> <%= title %> </h1>
<p>
<%= content %>
</p>
</body>
</html>
erb
max = 15_000
title = "hello world!"
content = "hello world!\n" * 10
max.times{
ERB.new(data).result(binding)
}
loop_count: 1

View file

@ -1,14 +0,0 @@
benchmark:
app_factorial: |
def fact(n)
if(n > 1)
n * fact(n-1)
else
1
end
end
100.times {
fact(5000)
}
loop_count: 1

View file

@ -1,12 +0,0 @@
benchmark:
app_fib: |
def fib n
if n < 3
1
else
fib(n-1) + fib(n-2)
end
end
fib(34)
loop_count: 1

File diff suppressed because one or more lines are too long

View file

@ -1,25 +0,0 @@
benchmark:
app_mandelbrot: |
require 'complex'
def mandelbrot? z
i = 0
while i<100
i += 1
z = z * z
return false if z.abs > 2
end
true
end
ary = []
(0..1000).each{|dx|
(0..1000).each{|dy|
x = dx / 50.0
y = dy / 50.0
c = Complex(x, y)
ary << c if mandelbrot?(c)
}
}
loop_count: 1

View file

@ -1,130 +0,0 @@
benchmark:
app_pentomino: |
# This program is contributed by Shin Nishiyama
# modified by K.Sasada
NP = 5
ROW = 8 + NP
COL = 8
$p = []
$b = []
$no = 0
def piece(n, a, nb)
nb.each{|x|
a[n] = x
if n == NP-1
$p << [a.sort]
else
nbc=nb.dup
[-ROW, -1, 1, ROW].each{|d|
if x+d > 0 and not a.include?(x+d) and not nbc.include?(x+d)
nbc << x+d
end
}
nbc.delete x
piece(n+1,a[0..n],nbc)
end
}
end
def kikaku(a)
a.collect {|x| x - a[0]}
end
def ud(a)
kikaku(a.collect {|x| ((x+NP)%ROW)-ROW*((x+NP)/ROW) }.sort)
end
def rl(a)
kikaku(a.collect {|x| ROW*((x+NP)/ROW)+ROW-((x+NP)%ROW)}.sort)
end
def xy(a)
kikaku(a.collect {|x| ROW*((x+NP)%ROW) + (x+NP)/ROW }.sort)
end
def mkpieces
piece(0,[],[0])
$p.each do |a|
a0 = a[0]
a[1] = ud(a0)
a[2] = rl(a0)
a[3] = ud(rl(a0))
a[4] = xy(a0)
a[5] = ud(xy(a0))
a[6] = rl(xy(a0))
a[7] = ud(rl(xy(a0)))
a.sort!
a.uniq!
end
$p.uniq!.sort! {|x,y| x[0] <=> y[0] }
end
def mkboard
(0...ROW*COL).each{|i|
if i % ROW >= ROW-NP
$b[i] = -2
else
$b[i] = -1
end
$b[3*ROW+3]=$b[3*ROW+4]=$b[4*ROW+3]=$b[4*ROW+4]=-2
}
end
def pboard
return # skip print
print "No. #$no\n"
(0...COL).each{|i|
print "|"
(0...ROW-NP).each{|j|
x = $b[i*ROW+j]
if x < 0
print "..|"
else
printf "%2d|",x+1
end
}
print "\n"
}
print "\n"
end
$pnum=[]
def setpiece(a,pos)
if a.length == $p.length then
$no += 1
pboard
return
end
while $b[pos] != -1
pos += 1
end
($pnum - a).each do |i|
$p[i].each do |x|
f = 0
x.each{|s|
if $b[pos+s] != -1
f=1
break
end
}
if f == 0 then
x.each{|s|
$b[pos+s] = i
}
a << i
setpiece(a.dup, pos)
a.pop
x.each{|s|
$b[pos+s] = -1
}
end
end
end
end
mkpieces
mkboard
$p[4] = [$p[4][0]]
$pnum = (0...$p.length).to_a
setpiece([],0)
loop_count: 1

View file

@ -1,11 +0,0 @@
benchmark:
app_raise: |
i = 0
while i<300000
i += 1
begin
raise
rescue
end
end
loop_count: 1

View file

@ -1,8 +0,0 @@
benchmark:
app_strconcat: |
i = 0
while i<2_000_000
"#{1+1} #{1+1} #{1+1}"
i += 1
end
loop_count: 1

View file

@ -1,15 +0,0 @@
benchmark:
app_tak: |
def tak x, y, z
unless y < x
z
else
tak( tak(x-1, y, z),
tak(y-1, z, x),
tak(z-1, x, y))
end
end
tak(18, 9, 0)
loop_count: 1

View file

@ -1,13 +0,0 @@
benchmark:
app_tarai: |
def tarai( x, y, z )
if x <= y
then y
else tarai(tarai(x-1, y, z),
tarai(y-1, z, x),
tarai(z-1, x, y))
end
end
tarai(12, 6, 0)
loop_count: 1

View file

@ -1,11 +0,0 @@
benchmark:
app_uri: |
require 'uri'
100_000.times{
uri = URI.parse('http://www.ruby-lang.org')
uri.scheme
uri.host
uri.port
}
loop_count: 1

View file

@ -1,5 +0,0 @@
benchmark:
array_sample_100k_10: |
arr = [*0...100000]
10_000.times {arr.sample 10}
loop_count: 1

View file

@ -1,5 +0,0 @@
benchmark:
array_sample_100k_11: |
arr = [*0...100000]
10_000.times {arr.sample 11}
loop_count: 1

View file

@ -1,5 +0,0 @@
benchmark:
array_sample_100k__100: |
arr = [*0...100000]
10_000.times {arr.sample 100}
loop_count: 1

View file

@ -1,5 +0,0 @@
benchmark:
array_sample_100k__1k: |
arr = [*0...100000]
10_000.times {arr.sample 1000}
loop_count: 1

View file

@ -1,5 +0,0 @@
benchmark:
array_sample_100k__6k: |
arr = [*0...100000]
10_000.times {arr.sample 6000}
loop_count: 1

View file

@ -1,5 +0,0 @@
benchmark:
array_sample_100k___10k: |
arr = [*0...100000]
10_000.times {arr.sample 10_000}
loop_count: 1

View file

@ -1,5 +0,0 @@
benchmark:
array_sample_100k___50k: |
arr = [*0...100000]
10_000.times {arr.sample 50_000}
loop_count: 1

View file

@ -1,17 +0,0 @@
benchmark:
array_shift: |
require 'benchmark'
Benchmark.bm do |x|
[10_000,1_000_000,100_000_000].each do |n|
ary = Array.new(n,0)
GC.start
x.report("#{n}:shift"){ ary.shift }
(0..4).each do |i|
ary = Array.new(n,0)
GC.start
x.report("#{n}:shift(#{i})"){ ary.shift(i) }
end
end
end
loop_count: 1

View file

@ -1,20 +0,0 @@
benchmark:
array_small_and: |
MIN_SIZE = ENV.fetch('SMALL_ARRAY_MIN', 0).to_i
MAX_SIZE = ENV.fetch('SMALL_ARRAY_MAX', 16).to_i
ITERATIONS = ENV.fetch('SMALL_ARRAY_ITERATIONS', 100).to_i
ARRAYS = (MIN_SIZE..MAX_SIZE).map do |size1|
(MIN_SIZE..MAX_SIZE).map do |size2|
[Array.new(size1) { rand(MAX_SIZE) }, Array.new(size2) { rand(MAX_SIZE) }]
end
end
ITERATIONS.times do
ARRAYS.each do |group|
group.each do |arr1, arr2|
arr1 & arr2
end
end
end
loop_count: 1

View file

@ -1,20 +0,0 @@
benchmark:
array_small_diff: |
MIN_SIZE = ENV.fetch('SMALL_ARRAY_MIN', 0).to_i
MAX_SIZE = ENV.fetch('SMALL_ARRAY_MAX', 16).to_i
ITERATIONS = ENV.fetch('SMALL_ARRAY_ITERATIONS', 100).to_i
ARRAYS = (MIN_SIZE..MAX_SIZE).map do |size1|
(MIN_SIZE..MAX_SIZE).map do |size2|
[Array.new(size1) { rand(MAX_SIZE) }, Array.new(size2) { rand(MAX_SIZE) }]
end
end
ITERATIONS.times do
ARRAYS.each do |group|
group.each do |arr1, arr2|
arr1 - arr2
end
end
end
loop_count: 1

View file

@ -1,20 +0,0 @@
benchmark:
array_small_or: |
MIN_SIZE = ENV.fetch('SMALL_ARRAY_MIN', 0).to_i
MAX_SIZE = ENV.fetch('SMALL_ARRAY_MAX', 16).to_i
ITERATIONS = ENV.fetch('SMALL_ARRAY_ITERATIONS', 100).to_i
ARRAYS = (MIN_SIZE..MAX_SIZE).map do |size1|
(MIN_SIZE..MAX_SIZE).map do |size2|
[Array.new(size1) { rand(MAX_SIZE) }, Array.new(size2) { rand(MAX_SIZE) }]
end
end
ITERATIONS.times do
ARRAYS.each do |group|
group.each do |arr1, arr2|
arr1 | arr2
end
end
end
loop_count: 1

View file

@ -1,5 +0,0 @@
benchmark:
array_sort_block: |
ary = Array.new(1000) { rand(1000) }
10000.times { ary.sort { |a, b| a <=> b } }
loop_count: 1

View file

@ -1,5 +0,0 @@
benchmark:
array_sort_float: |
arr = Array.new(1000) { rand }
10000.times { arr.sort }
loop_count: 1

View file

@ -1,5 +0,0 @@
benchmark:
array_values_at_int: |
ary = Array.new(10000) {|i| i}
100000.times { ary.values_at(500) }
loop_count: 1

View file

@ -1,5 +0,0 @@
benchmark:
array_values_at_range: |
ary = Array.new(10000) {|i| i}
100000.times { ary.values_at(1..2000) }
loop_count: 1

View file

@ -1,4 +0,0 @@
benchmark:
bighash: |
h = {}; 5000000.times {|n| h[n] = n }
loop_count: 1

View file

@ -0,0 +1,15 @@
def ack(m, n)
if m == 0 then
n + 1
elsif n == 0 then
ack(m - 1, 1)
else
ack(m - 1, ack(m, n - 1))
end
end
def the_answer_to_life_the_universe_and_everything
(ack(3,7).to_s.split(//).inject(0){|s,x| s+x.to_i}.to_s + "2" ).to_i
end
answer = the_answer_to_life_the_universe_and_everything

291
benchmark/bm_app_aobench.rb Normal file
View file

@ -0,0 +1,291 @@
# AO render benchmark
# Original program (C) Syoyo Fujita in Javascript (and other languages)
# https://code.google.com/p/aobench/
# Ruby(yarv2llvm) version by Hideki Miura
#
IMAGE_WIDTH = 256
IMAGE_HEIGHT = 256
NSUBSAMPLES = 2
NAO_SAMPLES = 8
class Vec
def initialize(x, y, z)
@x = x
@y = y
@z = z
end
attr_accessor :x, :y, :z
def vadd(b)
Vec.new(@x + b.x, @y + b.y, @z + b.z)
end
def vsub(b)
Vec.new(@x - b.x, @y - b.y, @z - b.z)
end
def vcross(b)
Vec.new(@y * b.z - @z * b.y,
@z * b.x - @x * b.z,
@x * b.y - @y * b.x)
end
def vdot(b)
@x * b.x + @y * b.y + @z * b.z
end
def vlength
Math.sqrt(@x * @x + @y * @y + @z * @z)
end
def vnormalize
len = vlength
v = Vec.new(@x, @y, @z)
if len > 1.0e-17 then
v.x = v.x / len
v.y = v.y / len
v.z = v.z / len
end
v
end
end
class Sphere
def initialize(center, radius)
@center = center
@radius = radius
end
attr_reader :center, :radius
def intersect(ray, isect)
rs = ray.org.vsub(@center)
b = rs.vdot(ray.dir)
c = rs.vdot(rs) - (@radius * @radius)
d = b * b - c
if d > 0.0 then
t = - b - Math.sqrt(d)
if t > 0.0 and t < isect.t then
isect.t = t
isect.hit = true
isect.pl = Vec.new(ray.org.x + ray.dir.x * t,
ray.org.y + ray.dir.y * t,
ray.org.z + ray.dir.z * t)
n = isect.pl.vsub(@center)
isect.n = n.vnormalize
else
0.0
end
end
nil
end
end
class Plane
def initialize(p, n)
@p = p
@n = n
end
def intersect(ray, isect)
d = -@p.vdot(@n)
v = ray.dir.vdot(@n)
v0 = v
if v < 0.0 then
v0 = -v
end
if v0 < 1.0e-17 then
return
end
t = -(ray.org.vdot(@n) + d) / v
if t > 0.0 and t < isect.t then
isect.hit = true
isect.t = t
isect.n = @n
isect.pl = Vec.new(ray.org.x + t * ray.dir.x,
ray.org.y + t * ray.dir.y,
ray.org.z + t * ray.dir.z)
end
nil
end
end
class Ray
def initialize(org, dir)
@org = org
@dir = dir
end
attr_accessor :org, :dir
end
class Isect
def initialize
@t = 10000000.0
@hit = false
@pl = Vec.new(0.0, 0.0, 0.0)
@n = Vec.new(0.0, 0.0, 0.0)
end
attr_accessor :t, :hit, :pl, :n
end
def clamp(f)
i = f * 255.5
if i > 255.0 then
i = 255.0
end
if i < 0.0 then
i = 0.0
end
i.to_i
end
def otherBasis(basis, n)
basis[2] = Vec.new(n.x, n.y, n.z)
basis[1] = Vec.new(0.0, 0.0, 0.0)
if n.x < 0.6 and n.x > -0.6 then
basis[1].x = 1.0
elsif n.y < 0.6 and n.y > -0.6 then
basis[1].y = 1.0
elsif n.z < 0.6 and n.z > -0.6 then
basis[1].z = 1.0
else
basis[1].x = 1.0
end
basis[0] = basis[1].vcross(basis[2])
basis[0] = basis[0].vnormalize
basis[1] = basis[2].vcross(basis[0])
basis[1] = basis[1].vnormalize
end
class Scene
def initialize
@spheres = Array.new
@spheres[0] = Sphere.new(Vec.new(-2.0, 0.0, -3.5), 0.5)
@spheres[1] = Sphere.new(Vec.new(-0.5, 0.0, -3.0), 0.5)
@spheres[2] = Sphere.new(Vec.new(1.0, 0.0, -2.2), 0.5)
@plane = Plane.new(Vec.new(0.0, -0.5, 0.0), Vec.new(0.0, 1.0, 0.0))
end
def ambient_occlusion(isect)
basis = Array.new
otherBasis(basis, isect.n)
ntheta = NAO_SAMPLES
nphi = NAO_SAMPLES
eps = 0.0001
occlusion = 0.0
p0 = Vec.new(isect.pl.x + eps * isect.n.x,
isect.pl.y + eps * isect.n.y,
isect.pl.z + eps * isect.n.z)
nphi.times do |j|
ntheta.times do |i|
r = rand
phi = 2.0 * 3.14159265 * rand
x = Math.cos(phi) * Math.sqrt(1.0 - r)
y = Math.sin(phi) * Math.sqrt(1.0 - r)
z = Math.sqrt(r)
rx = x * basis[0].x + y * basis[1].x + z * basis[2].x
ry = x * basis[0].y + y * basis[1].y + z * basis[2].y
rz = x * basis[0].z + y * basis[1].z + z * basis[2].z
raydir = Vec.new(rx, ry, rz)
ray = Ray.new(p0, raydir)
occisect = Isect.new
@spheres[0].intersect(ray, occisect)
@spheres[1].intersect(ray, occisect)
@spheres[2].intersect(ray, occisect)
@plane.intersect(ray, occisect)
if occisect.hit then
occlusion = occlusion + 1.0
else
0.0
end
end
end
occlusion = (ntheta.to_f * nphi.to_f - occlusion) / (ntheta.to_f * nphi.to_f)
Vec.new(occlusion, occlusion, occlusion)
end
def render(w, h, nsubsamples)
cnt = 0
nsf = nsubsamples.to_f
h.times do |y|
w.times do |x|
rad = Vec.new(0.0, 0.0, 0.0)
# Subsampling
nsubsamples.times do |v|
nsubsamples.times do |u|
cnt = cnt + 1
wf = w.to_f
hf = h.to_f
xf = x.to_f
yf = y.to_f
uf = u.to_f
vf = v.to_f
px = (xf + (uf / nsf) - (wf / 2.0)) / (wf / 2.0)
py = -(yf + (vf / nsf) - (hf / 2.0)) / (hf / 2.0)
eye = Vec.new(px, py, -1.0).vnormalize
ray = Ray.new(Vec.new(0.0, 0.0, 0.0), eye)
isect = Isect.new
@spheres[0].intersect(ray, isect)
@spheres[1].intersect(ray, isect)
@spheres[2].intersect(ray, isect)
@plane.intersect(ray, isect)
if isect.hit then
col = ambient_occlusion(isect)
rad.x = rad.x + col.x
rad.y = rad.y + col.y
rad.z = rad.z + col.z
end
end
end
r = rad.x / (nsf * nsf)
g = rad.y / (nsf * nsf)
b = rad.z / (nsf * nsf)
printf("%c", clamp(r))
printf("%c", clamp(g))
printf("%c", clamp(b))
end
nil
end
nil
end
end
alias printf_orig printf
def printf *args
end
# File.open("ao.ppm", "w") do |fp|
printf("P6\n")
printf("%d %d\n", IMAGE_WIDTH, IMAGE_HEIGHT)
printf("255\n", IMAGE_WIDTH, IMAGE_HEIGHT)
Scene.new.render(IMAGE_WIDTH, IMAGE_HEIGHT, NSUBSAMPLES)
# end
undef printf
alias printf printf_orig

25
benchmark/bm_app_erb.rb Normal file
View file

@ -0,0 +1,25 @@
#
# Create many HTML strings with ERB.
#
require 'erb'
data = <<erb
<html>
<head> <%= title %> </head>
<body>
<h1> <%= title %> </h1>
<p>
<%= content %>
</p>
</body>
</html>
erb
max = 15_000
title = "hello world!"
content = "hello world!\n" * 10
max.times{
ERB.new(data).result(binding)
}

View file

@ -0,0 +1,11 @@
def fact(n)
if(n > 1)
n * fact(n-1)
else
1
end
end
100.times {
fact(5000)
}

10
benchmark/bm_app_fib.rb Normal file
View file

@ -0,0 +1,10 @@
def fib n
if n < 3
1
else
fib(n-1) + fib(n-2)
end
end
fib(34)

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,23 @@
require 'complex'
def mandelbrot? z
i = 0
while i<100
i += 1
z = z * z
return false if z.abs > 2
end
true
end
ary = []
(0..1000).each{|dx|
(0..1000).each{|dy|
x = dx / 50.0
y = dy / 50.0
c = Complex(x, y)
ary << c if mandelbrot?(c)
}
}

View file

@ -0,0 +1,130 @@
#!/usr/local/bin/ruby
# This program is contributed by Shin Nishiyama
# modified by K.Sasada
NP = 5
ROW = 8 + NP
COL = 8
$p = []
$b = []
$no = 0
def piece(n, a, nb)
nb.each{|x|
a[n] = x
if n == NP-1
$p << [a.sort]
else
nbc=nb.dup
[-ROW, -1, 1, ROW].each{|d|
if x+d > 0 and not a.include?(x+d) and not nbc.include?(x+d)
nbc << x+d
end
}
nbc.delete x
piece(n+1,a[0..n],nbc)
end
}
end
def kikaku(a)
a.collect {|x| x - a[0]}
end
def ud(a)
kikaku(a.collect {|x| ((x+NP)%ROW)-ROW*((x+NP)/ROW) }.sort)
end
def rl(a)
kikaku(a.collect {|x| ROW*((x+NP)/ROW)+ROW-((x+NP)%ROW)}.sort)
end
def xy(a)
kikaku(a.collect {|x| ROW*((x+NP)%ROW) + (x+NP)/ROW }.sort)
end
def mkpieces
piece(0,[],[0])
$p.each do |a|
a0 = a[0]
a[1] = ud(a0)
a[2] = rl(a0)
a[3] = ud(rl(a0))
a[4] = xy(a0)
a[5] = ud(xy(a0))
a[6] = rl(xy(a0))
a[7] = ud(rl(xy(a0)))
a.sort!
a.uniq!
end
$p.uniq!.sort! {|x,y| x[0] <=> y[0] }
end
def mkboard
(0...ROW*COL).each{|i|
if i % ROW >= ROW-NP
$b[i] = -2
else
$b[i] = -1
end
$b[3*ROW+3]=$b[3*ROW+4]=$b[4*ROW+3]=$b[4*ROW+4]=-2
}
end
def pboard
return # skip print
print "No. #$no\n"
(0...COL).each{|i|
print "|"
(0...ROW-NP).each{|j|
x = $b[i*ROW+j]
if x < 0
print "..|"
else
printf "%2d|",x+1
end
}
print "\n"
}
print "\n"
end
$pnum=[]
def setpiece(a,pos)
if a.length == $p.length then
$no += 1
pboard
return
end
while $b[pos] != -1
pos += 1
end
($pnum - a).each do |i|
$p[i].each do |x|
f = 0
x.each{|s|
if $b[pos+s] != -1
f=1
break
end
}
if f == 0 then
x.each{|s|
$b[pos+s] = i
}
a << i
setpiece(a.dup, pos)
a.pop
x.each{|s|
$b[pos+s] = -1
}
end
end
end
end
mkpieces
mkboard
$p[4] = [$p[4][0]]
$pnum = (0...$p.length).to_a
setpiece([],0)

View file

@ -0,0 +1,8 @@
i = 0
while i<300000
i += 1
begin
raise
rescue
end
end

View file

@ -0,0 +1,5 @@
i = 0
while i<2_000_000
"#{1+1} #{1+1} #{1+1}"
i += 1
end

13
benchmark/bm_app_tak.rb Normal file
View file

@ -0,0 +1,13 @@
def tak x, y, z
unless y < x
z
else
tak( tak(x-1, y, z),
tak(y-1, z, x),
tak(z-1, x, y))
end
end
tak(18, 9, 0)

10
benchmark/bm_app_tarai.rb Normal file
View file

@ -0,0 +1,10 @@
def tarai( x, y, z )
if x <= y
then y
else tarai(tarai(x-1, y, z),
tarai(y-1, z, x),
tarai(z-1, x, y))
end
end
tarai(12, 6, 0)

8
benchmark/bm_app_uri.rb Normal file
View file

@ -0,0 +1,8 @@
require 'uri'
100_000.times{
uri = URI.parse('http://www.ruby-lang.org')
uri.scheme
uri.host
uri.port
}

View file

@ -0,0 +1,2 @@
arr = [*0...100000]
10_000.times {arr.sample 10}

View file

@ -0,0 +1,2 @@
arr = [*0...100000]
10_000.times {arr.sample 11}

View file

@ -0,0 +1,2 @@
arr = [*0...100000]
10_000.times {arr.sample 100}

View file

@ -0,0 +1,2 @@
arr = [*0...100000]
10_000.times {arr.sample 1000}

View file

@ -0,0 +1,2 @@
arr = [*0...100000]
10_000.times {arr.sample 6000}

View file

@ -0,0 +1,2 @@
arr = [*0...100000]
10_000.times {arr.sample 10_000}

View file

@ -0,0 +1,2 @@
arr = [*0...100000]
10_000.times {arr.sample 50_000}

View file

@ -0,0 +1,14 @@
require 'benchmark'
Benchmark.bm do |x|
[10_000,1_000_000,100_000_000].each do |n|
ary = Array.new(n,0)
GC.start
x.report("#{n}:shift"){ ary.shift }
(0..4).each do |i|
ary = Array.new(n,0)
GC.start
x.report("#{n}:shift(#{i})"){ ary.shift(i) }
end
end
end

View file

@ -0,0 +1,17 @@
MIN_SIZE = ENV.fetch('SMALL_ARRAY_MIN', 0).to_i
MAX_SIZE = ENV.fetch('SMALL_ARRAY_MAX', 16).to_i
ITERATIONS = ENV.fetch('SMALL_ARRAY_ITERATIONS', 100).to_i
ARRAYS = (MIN_SIZE..MAX_SIZE).map do |size1|
(MIN_SIZE..MAX_SIZE).map do |size2|
[Array.new(size1) { rand(MAX_SIZE) }, Array.new(size2) { rand(MAX_SIZE) }]
end
end
ITERATIONS.times do
ARRAYS.each do |group|
group.each do |arr1, arr2|
arr1 & arr2
end
end
end

View file

@ -0,0 +1,17 @@
MIN_SIZE = ENV.fetch('SMALL_ARRAY_MIN', 0).to_i
MAX_SIZE = ENV.fetch('SMALL_ARRAY_MAX', 16).to_i
ITERATIONS = ENV.fetch('SMALL_ARRAY_ITERATIONS', 100).to_i
ARRAYS = (MIN_SIZE..MAX_SIZE).map do |size1|
(MIN_SIZE..MAX_SIZE).map do |size2|
[Array.new(size1) { rand(MAX_SIZE) }, Array.new(size2) { rand(MAX_SIZE) }]
end
end
ITERATIONS.times do
ARRAYS.each do |group|
group.each do |arr1, arr2|
arr1 - arr2
end
end
end

View file

@ -0,0 +1,17 @@
MIN_SIZE = ENV.fetch('SMALL_ARRAY_MIN', 0).to_i
MAX_SIZE = ENV.fetch('SMALL_ARRAY_MAX', 16).to_i
ITERATIONS = ENV.fetch('SMALL_ARRAY_ITERATIONS', 100).to_i
ARRAYS = (MIN_SIZE..MAX_SIZE).map do |size1|
(MIN_SIZE..MAX_SIZE).map do |size2|
[Array.new(size1) { rand(MAX_SIZE) }, Array.new(size2) { rand(MAX_SIZE) }]
end
end
ITERATIONS.times do
ARRAYS.each do |group|
group.each do |arr1, arr2|
arr1 | arr2
end
end
end

View file

@ -0,0 +1,2 @@
ary = Array.new(1000) { rand(1000) }
10000.times { ary.sort { |a, b| a <=> b } }

View file

@ -0,0 +1,2 @@
arr = Array.new(1000) { rand }
10000.times { arr.sort }

View file

@ -0,0 +1,2 @@
ary = Array.new(10000) {|i| i}
100000.times { ary.values_at(500) }

View file

@ -0,0 +1,2 @@
ary = Array.new(10000) {|i| i}
100000.times { ary.values_at(1..2000) }

1
benchmark/bm_bighash.rb Normal file
View file

@ -0,0 +1 @@
h = {}; 5000000.times {|n| h[n] = n }

View file

@ -0,0 +1,5 @@
require 'tmpdir'
max = 100_000
Dir.mktmpdir('bm_dir_empty_p') do |dir|
max.times { Dir.empty?(dir) }
end

View file

@ -0,0 +1,25 @@
require 'erb'
data = <<erb
<html>
<head> <%= title %> </head>
<body>
<h1> <%= title %> </h1>
<p>
<%= content %>
</p>
</body>
</html>
erb
max = 1_500_000
title = "hello world!"
content = "hello world!\n" * 10
src = "def self.render(title, content); #{ERB.new(data).src}; end"
mod = Module.new
mod.instance_eval(src, "(ERB)")
max.times do
mod.render(title, content)
end

View file

@ -0,0 +1,9 @@
# chmod file
require 'tempfile'
max = 200_000
tmp = Tempfile.new('chmod')
path = tmp.path
max.times do
File.chmod(0777, path)
end
tmp.close!

View file

@ -0,0 +1,11 @@
# rename file
require 'tempfile'
max = 100_000
tmp = [ Tempfile.new('rename-a'), Tempfile.new('rename-b') ]
a, b = tmp.map { |x| x.path }
tmp.each { |t| t.close } # Windows can't rename files without closing them
max.times do
File.rename(a, b)
File.rename(b, a)
end

View file

@ -0,0 +1,4 @@
h = {}
syms = ('a'..'z').map { |s| s.to_sym }
syms.each { |s| h[s] = 1 }
200_000.times { syms.each { |s| h[s] } }

View file

@ -0,0 +1,21 @@
# [ruby-core:70129] [Bug #11396]
collection_size = 200000
sample_size = 10000
values = (1..collection_size).to_a.map do |x|
"THIS IS A LONGER STRING THAT IS ALSO UNIQUE #{x}"
end
symbol_hash = {}
values.each do |x|
symbol_hash[x.to_sym] = 1
end
# use the same samples each time to minimize deviations
rng = Random.new(0)
symbol_sample_array = values.sample(sample_size, random: rng).map(&:to_sym)
3000.times do
symbol_sample_array.each { |x| symbol_hash[x] }
end

View file

@ -0,0 +1,4 @@
h = {}
nums = (1..26).to_a
nums.each { |i| h[i] = i }
200_000.times { nums.each { |s| h[s] } }

View file

@ -0,0 +1,4 @@
h = {}
strs = [*1..10000].map! {|i| i.fdiv(10)}
strs.each { |s| h[s] = s }
50.times { strs.each { |s| h[s] } }

View file

@ -0,0 +1,5 @@
h = {}
strs = ('a'..'z').to_a.map!(&:freeze)
strs.each { |s| h[s] = s }
strs = ('A'..'Z').to_a
200_000.times { strs.each { |s| h[s] } }

View file

@ -0,0 +1,4 @@
h = {}
strs = ('a'..'z').to_a.map!(&:freeze)
strs.each { |s| h[s] = s }
200_000.times { strs.each { |s| h[s] } }

View file

@ -0,0 +1,9 @@
h = {}
syms = ('a'..'z').to_a
begin
syms = eval("%i[#{syms.join(' ')}]")
rescue SyntaxError # <= 1.9.3
syms.map!(&:to_sym)
end
syms.each { |s| h[s] = s }
200_000.times { syms.each { |s| h[s] } }

View file

@ -0,0 +1,13 @@
h = {}
syms = %w[puts warn syswrite write stat bacon lettuce tomato
some symbols in this array may already be interned others should not be
hash browns make good breakfast but not cooked using prime numbers
shift for division entries delete_if keys exist?
]
begin
syms = eval("%i[#{syms.join(' ')}]")
rescue SyntaxError # <= 1.9.3
syms.map!(&:to_sym)
end
syms.each { |s| h[s] = s }
200_000.times { syms.each { |s| h[s] } }

View file

@ -0,0 +1,9 @@
h = {}
10000.times do |i|
h[i] = nil
end
1000.times do
h.flatten
end

View file

@ -0,0 +1,4 @@
h = {}.compare_by_identity
strs = (1..10000).to_a.map!(&:to_f)
strs.each { |s| h[s] = s }
50.times { strs.each { |s| h[s] } }

View file

@ -0,0 +1,4 @@
h = {}.compare_by_identity
nums = (1..26).to_a
nums.each { |n| h[n] = n }
200_000.times { nums.each { |n| h[n] } }

View file

@ -0,0 +1,4 @@
h = {}.compare_by_identity
objs = 26.times.map { Object.new }
objs.each { |o| h[o] = o }
200_000.times { objs.each { |o| h[o] } }

View file

@ -0,0 +1,4 @@
h = {}.compare_by_identity
strs = ('a'..'z').to_a
strs.each { |s| h[s] = s }
200_000.times { strs.each { |s| h[s] } }

View file

@ -0,0 +1,4 @@
h = {}.compare_by_identity
syms = ('a'..'z').to_a.map(&:to_sym)
syms.each { |s| h[s] = s }
200_000.times { syms.each { |s| h[s] } }

View file

@ -0,0 +1,9 @@
h = {}
10000.times do |i|
h[i] = nil
end
5000.times do
h.keys
end

View file

@ -0,0 +1,4 @@
k1 = "Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong";
k2 = "Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping Pong Ping";
h = {k1 => 0, k2 => 0};
3000000.times{|i| k = i % 2 ? k2 : k1; h [k] = h[k] + 1}

View file

@ -0,0 +1,10 @@
h = {}
10000.times do |i|
h[i] = nil
end
50000.times do
k, v = h.shift
h[k] = v
end

View file

@ -0,0 +1,10 @@
h = {}
(16384..65536).each do |i|
h[i] = nil
end
300000.times do
k, v = h.shift
h[k] = v
end

View file

@ -0,0 +1,10 @@
h = {}
(0xff4000..0xffffff).each do |i|
h[i] = nil
end
300000.times do
k, v = h.shift
h[k] = v
end

View file

@ -0,0 +1,10 @@
h = {}
(0xffff4000..0xffffffff).each do |i|
h[i] = nil
end
300000.times do
k, v = h.shift
h[k] = v
end

View file

@ -0,0 +1 @@
1000000.times.map{|i| a={}; 2.times{|j| a[j]=j}; a}

View file

@ -0,0 +1 @@
1000000.times.map{|i| a={}; 4.times{|j| a[j]=j}; a}

View file

@ -0,0 +1 @@
1000000.times.map{|i| a={}; 8.times{|j| a[j]=j}; a}

View file

@ -0,0 +1,9 @@
h = {}
10000.times do |i|
h[i] = nil
end
5000.times do |i|
[i].map(&h)
end

View file

@ -0,0 +1,9 @@
h = {}
10000.times do |i|
h[i] = nil
end
5000.times do
h.values
end

1
benchmark/bm_int_quo.rb Normal file
View file

@ -0,0 +1 @@
5000000.times { 42.quo(3) }

View file

@ -0,0 +1,24 @@
# The goal of this is to use a synthetic (non-IO) reader
# to trigger the read/write loop of IO.copy_stream,
# bypassing in-kernel mechanisms like sendfile for zero copy,
# so we wrap the /dev/zero IO object:
class Zero
def initialize
@n = 100000
@in = File.open('/dev/zero', 'rb')
end
def read(len, buf)
return if (@n -= 1) == 0
@in.read(len, buf)
end
end
begin
src = Zero.new
dst = File.open(IO::NULL, 'wb')
n = IO.copy_stream(src, dst)
rescue Errno::ENOENT
# not *nix
end if IO.respond_to?(:copy_stream) && IO.const_defined?(:NULL)

View file

@ -0,0 +1,35 @@
# The goal of this is to use a synthetic (non-IO) reader
# to trigger the read/write loop of IO.copy_stream,
# bypassing in-kernel mechanisms like sendfile for zero copy,
# so we wrap the /dev/zero IO object:
class Zero
def initialize
@n = 100000
@in = File.open('/dev/zero', 'rb')
end
def read(len, buf)
return if (@n -= 1) == 0
@in.read(len, buf)
end
end
begin
require 'socket'
src = Zero.new
rd, wr = UNIXSocket.pair
pid = fork do
wr.close
buf = String.new
while rd.read(16384, buf)
end
end
rd.close
IO.copy_stream(src, wr)
rescue Errno::ENOENT, NotImplementedError, NameError
# not *nix: missing /dev/zero, fork, or UNIXSocket
rescue LoadError # no socket?
ensure
wr.close if wr
Process.waitpid(pid) if pid
end if IO.respond_to?(:copy_stream)

View file

@ -0,0 +1,13 @@
#
# Create files
#
max = 200_000
file = './tmpfile_of_bm_io_file_create'
max.times{
f = open(file, 'w')
f.close#(true)
}
File.unlink(file)

View file

@ -0,0 +1,15 @@
#
# Seek and Read file.
#
require 'tempfile'
max = 200_000
str = "Hello world! " * 1000
f = Tempfile.new('yarv-benchmark')
f.write str
max.times{
f.seek 0
f.read
}

View file

@ -0,0 +1,14 @@
#
# Seek and Write file.
#
require 'tempfile'
max = 200_000
str = "Hello world! " * 1000
f = Tempfile.new('yarv-benchmark')
max.times{
f.seek 0
f.write str
}

View file

@ -0,0 +1,22 @@
nr = 1_000_000
i = 0
msg = '.'
buf = '.'
noex = { exception: false }
begin
r, w = IO.pipe
while i < nr
i += 1
w.write_nonblock(msg, noex)
r.read_nonblock(1, buf, noex)
end
rescue ArgumentError # old Rubies
while i < nr
i += 1
w.write_nonblock(msg)
r.read_nonblock(1, buf)
end
ensure
r.close
w.close
end

View file

@ -0,0 +1,21 @@
nr = 1_000_000
i = 0
msg = '.'
buf = '.'
begin
r, w = IO.pipe
while i < nr
i += 1
w.write_nonblock(msg, exception: false)
r.read_nonblock(1, buf, exception: false)
end
rescue ArgumentError # old Rubies
while i < nr
i += 1
w.write_nonblock(msg)
r.read_nonblock(1, buf)
end
ensure
r.close
w.close
end

View file

@ -0,0 +1,13 @@
# Measure uncontended GVL performance via read/write with 1:1 threading
# If we switch to M:N threading, this will benchmark something else...
r, w = IO.pipe
src = '0'.freeze
dst = String.new
i = 0
while i < 1_000_000
i += 1
w.write(src)
r.read(1, dst)
end
w.close
r.close

View file

@ -0,0 +1,9 @@
# IO.select performance
w = [ IO.pipe[1] ];
nr = 1000000
nr.times {
IO.select nil, w
}

View file

@ -0,0 +1,22 @@
# IO.select performance. worst case of single fd.
ios = []
nr = 1000000
if defined?(Process::RLIMIT_NOFILE)
max = Process.getrlimit(Process::RLIMIT_NOFILE)[0]
else
max = 64
end
puts "max fd: #{max} (results not apparent with <= 1024 max fd)"
((max / 2) - 10).times do
ios.concat IO.pipe
end
last = [ ios[-1] ]
puts "last IO: #{last[0].inspect}"
nr.times do
IO.select nil, last
end

View file

@ -0,0 +1,21 @@
# IO.select performance. a lot of fd
ios = []
nr = 100
if defined?(Process::RLIMIT_NOFILE)
max = Process.getrlimit(Process::RLIMIT_NOFILE)[0]
else
max = 64
end
puts "max fd: #{max} (results not apparent with <= 1024 max fd)"
(max - 10).times do
r, w = IO.pipe
r.close
ios.push w
end
nr.times do
IO.select nil, ios
end

Some files were not shown because too many files have changed in this diff Show more