Skip to content

Commit

Permalink
Add benchmarks from HN blog post (#260)
Browse files Browse the repository at this point in the history
* Add benchmarks from HN blog post

* Add new benchmarks to benchmarks.yml
  • Loading branch information
maximecb authored Jan 8, 2024
1 parent 6a70de9 commit da7585a
Show file tree
Hide file tree
Showing 4 changed files with 228 additions and 0 deletions.
6 changes: 6 additions & 0 deletions benchmarks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ rubykon:
desc: Ruby solver for Go (the boardgame.) Runs 1,000 iterations forward from an initial starting board.
tinygql:
desc: TinyGQL gem parsing a large file in pure Ruby
nqueens:
desc: solver for the N-Queens problem
sudoku:
desc: sudoku solver
matmul:
desc: matrix multiplication benchmark

#
# MicroBenchmarks
Expand Down
43 changes: 43 additions & 0 deletions benchmarks/matmul.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
require_relative '../harness/loader'

def matgen(n)
tmp = 1.0 / n / n
a = Array.new(n) { Array.new(n) { 0 } }
for i in 0 .. n-1
for j in 0 .. n-1
a[i][j] = tmp * (i - j) * (i + j)
end
end
return a
end

def matmul(a, b)
m = a.length
n = a[0].length
p = b[0].length
c = Array.new(m) { Array.new(p) { 0 } }
for i in 0 .. m-1
ci = c[i]
for k in 0 .. n-1
aik = a[i][k]
bk = b[k]
for j in 0 .. p-1
ci[j] += aik * bk[j]
end
end
end
return c
end

n = 300
if ARGV.length >= 1
n = ARGV[0].to_i
end
n = n / 2 * 2

run_benchmark(20) do
a = matgen(n)
b = matgen(n)
c = matmul(a, b)
#puts c[n/2][n/2]
end
44 changes: 44 additions & 0 deletions benchmarks/nqueens.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
require_relative '../harness/loader'

def nq_solve(n)
a = Array.new(n) { -1 }
l = Array.new(n) { 0 }
c = Array.new(n) { 0 }
r = Array.new(n) { 0 }
y0 = (1<<n) - 1
m = 0
k = 0
while k >= 0 do
y = (l[k] | c[k] | r[k]) & y0
if (y ^ y0) >> (a[k] + 1) != 0 then
i = a[k] + 1
while i < n and (y & 1<<i) != 0 do
i += 1
end
if k < n - 1 then
z = 1<<i
a[k] = i
k += 1
l[k] = (l[k-1]|z)<<1
c[k] = c[k-1]|z
r[k] = (r[k-1]|z)>>1
else
m += 1
k -= 1
end
else
a[k] = -1
k -= 1
end
end
return m
end

n = 12
if ARGV.length() > 0 then
n = ARGV[0].to_i
end

run_benchmark(40) do
nq_solve(n)
end
135 changes: 135 additions & 0 deletions benchmarks/sudoku.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
require_relative '../harness/loader'

def sd_genmat()
mr = Array.new(324) { [] }
mc = Array.new(729) { [] }
r = 0
(0...9).each do |i|
(0...9).each do |j|
(0...9).each do |k|
mc[r] = [ 9 * i + j, (i/3*3 + j/3) * 9 + k + 81, 9 * i + k + 162, 9 * j + k + 243 ]
r += 1
end
end
end
(0...729).each do |r|
(0...4).each do |c2|
mr[mc[r][c2]].push(r)
end
end
return mr, mc
end

def sd_update(mr, mc, sr, sc, r, v)
min, min_c = 10, 0
(0...4).each do |c2|
if v > 0 then sc[mc[r][c2]] += 128
else sc[mc[r][c2]] -= 128 end
end
(0...4).each do |c2|
c = mc[r][c2]
if v > 0 then
(0...9).each do |r2|
rr = mr[c][r2]
sr[rr] += + 1
if sr[rr] == 1 then
p = mc[rr]
sc[p[0]] -= 1; sc[p[1]] -= 1; sc[p[2]] -= 1; sc[p[3]] -= 1
if sc[p[0]] < min then min, min_c = sc[p[0]], p[0] end
if sc[p[1]] < min then min, min_c = sc[p[1]], p[1] end
if sc[p[2]] < min then min, min_c = sc[p[2]], p[2] end
if sc[p[3]] < min then min, min_c = sc[p[3]], p[3] end
end
end
else
(0...9).each do |r2|
rr = mr[c][r2]
sr[rr] -= 1
if sr[rr] == 0 then
p = mc[rr]
sc[p[0]] += 1; sc[p[1]] += 1; sc[p[2]] += 1; sc[p[3]] += 1
end
end
end
end
return min, min_c
end

def sd_solve(mr, mc, s)
ret, sr, sc, hints = [], Array.new(729) { 0 }, Array.new(324) { 9 }, 0
(0...81).each do |i|
a = (s[i].chr >= '1' and s[i].chr <= '9')? s[i].ord - 49 : -1
if a >= 0 then sd_update(mr, mc, sr, sc, i * 9 + a, 1); hints += 1 end
end
cr, cc = Array.new(81) { -1 }, Array.new(81) { 0 }
i, min, dir = 0, 10, 1
loop do
while i >= 0 and i < 81 - hints do
if dir == 1 then
if min > 1 then
(0...324).each do |c|
if sc[c] < min then
min, cc[i] = sc[c], c
if min < 2 then break end
end
end
end
if min == 0 or min == 10 then cr[i], dir, i = -1, -1, i - 1 end
end
c = cc[i]
if dir == -1 and cr[i] >= 0 then sd_update(mr, mc, sr, sc, mr[c][cr[i]], -1) end
r2_ = 9
(cr[i]+1...9).each do |r2|
if sr[mr[c][r2]] == 0 then r2_ = r2; break end
end
if r2_ < 9 then
min, cc[i+1] = sd_update(mr, mc, sr, sc, mr[c][r2_], 1)
cr[i], dir, i = r2_, 1, i + 1
else cr[i], dir, i = -1, -1, i - 1 end
end
if i < 0 then break end
o = []
(0...81).each do |j| o.push(s[j].ord - 48) end
(0...i).each do |j|
r = mr[cc[j]][cr[j]]
o[r/9] = r % 9 + 1
end
ret.push(o)
i, dir = i - 1, -1
end
return ret
end

hard20 = [
"..............3.85..1.2.......5.7.....4...1...9.......5......73..2.1........4...9",
".......12........3..23..4....18....5.6..7.8.......9.....85.....9...4.5..47...6...",
".2..5.7..4..1....68....3...2....8..3.4..2.5.....6...1...2.9.....9......57.4...9..",
"........3..1..56...9..4..7......9.5.7.......8.5.4.2....8..2..9...35..1..6........",
"12.3....435....1....4........54..2..6...7.........8.9...31..5.......9.7.....6...8",
"1.......2.9.4...5...6...7...5.9.3.......7.......85..4.7.....6...3...9.8...2.....1",
".......39.....1..5..3.5.8....8.9...6.7...2...1..4.......9.8..5..2....6..4..7.....",
"12.3.....4.....3....3.5......42..5......8...9.6...5.7...15..2......9..6......7..8",
"..3..6.8....1..2......7...4..9..8.6..3..4...1.7.2.....3....5.....5...6..98.....5.",
"1.......9..67...2..8....4......75.3...5..2....6.3......9....8..6...4...1..25...6.",
"..9...4...7.3...2.8...6...71..8....6....1..7.....56...3....5..1.4.....9...2...7..",
"....9..5..1.....3...23..7....45...7.8.....2.......64...9..1.....8..6......54....7",
"4...3.......6..8..........1....5..9..8....6...7.2........1.27..5.3....4.9........",
"7.8...3.....2.1...5.........4.....263...8.......1...9..9.6....4....7.5...........",
"3.7.4...........918........4.....7.....16.......25..........38..9....5...2.6.....",
"........8..3...4...9..2..6.....79.......612...6.5.2.7...8...5...1.....2.4.5.....3",
".......1.4.........2...........5.4.7..8...3....1.9....3..4..2...5.1........8.6...",
".......12....35......6...7.7.....3.....4..8..1...........12.....8.....4..5....6..",
"1.......2.9.4...5...6...7...5.3.4.......6........58.4...2...6...3...9.8.7.......1",
".....1.2.3...4.5.....6....7..2.....1.8..9..3.4.....8..5....2....9..3.4....67....."
]
mr, mc = sd_genmat()

run_benchmark(20) do
n = 4
(0...n).each do |i|
hard20.each do |l|
ret = sd_solve(mr, mc, l)
ret.each do |s| s.join end
end
end
end

0 comments on commit da7585a

Please sign in to comment.