Get binary_trees benchmark working.

Wren is actually doing well in it:

wren      mean: 1.9441 median: 1.9428 std_dev: 0.0260
lua       mean: 3.5992 median: 3.6033 std_dev: 0.0156
python    mean: 3.6667 median: 3.7097 std_dev: 0.1340
ruby      mean: 1.3941 median: 1.3914 std_dev: 0.0091
This commit is contained in:
Bob Nystrom
2013-11-29 16:19:13 -08:00
parent ce89dd9c2f
commit edb9032052
6 changed files with 240 additions and 17 deletions

View File

@ -0,0 +1,54 @@
-- The Computer Language Benchmarks Game
-- http://shootout.alioth.debian.org/
-- contributed by Mike Pall
local function BottomUpTree(item, depth)
if depth > 0 then
local i = item + item
depth = depth - 1
local left, right = BottomUpTree(i-1, depth), BottomUpTree(i, depth)
return { item, left, right }
else
return { item }
end
end
local function ItemCheck(tree)
if tree[2] then
return tree[1] + ItemCheck(tree[2]) - ItemCheck(tree[3])
else
return tree[1]
end
end
local N = 14
local mindepth = 4
local maxdepth = mindepth + 2
if maxdepth < N then maxdepth = N end
local start = os.clock()
do
local stretchdepth = maxdepth + 1
local stretchtree = BottomUpTree(0, stretchdepth)
io.write(string.format("stretch tree of depth %d\t check: %d\n",
stretchdepth, ItemCheck(stretchtree)))
end
local longlivedtree = BottomUpTree(0, maxdepth)
for depth=mindepth,maxdepth,2 do
local iterations = 2 ^ (maxdepth - depth + mindepth)
local check = 0
for i=1,iterations do
check = check + ItemCheck(BottomUpTree(1, depth)) +
ItemCheck(BottomUpTree(-1, depth))
end
io.write(string.format("%d\t trees of depth %d\t check: %d\n",
iterations*2, depth, check))
end
io.write(string.format("long lived tree of depth %d\t check: %d\n",
maxdepth, ItemCheck(longlivedtree)))
io.write(string.format("elapsed: %.8f\n", os.clock() - start))

40
benchmark/binary_trees.py Normal file
View File

@ -0,0 +1,40 @@
# The Computer Language Benchmarks Game
# http://shootout.alioth.debian.org/
#
# contributed by Antoine Pitrou
# modified by Dominique Wahli
# modified by Heinrich Acker
import time
def make_tree(item, depth):
if not depth: return item, None, None
item2 = item + item
depth -= 1
return item, make_tree(item2 - 1, depth), make_tree(item2, depth)
def check_tree((item, left, right)):
if not left: return item
return item + check_tree(left) - check_tree(right)
min_depth = 4
max_depth = max(min_depth + 2, 14)
stretch_depth = max_depth + 1
start = time.clock()
print "stretch tree of depth %d\t check:" % stretch_depth, check_tree(make_tree(0, stretch_depth))
long_lived_tree = make_tree(0, max_depth)
iterations = 2**max_depth
for depth in xrange(min_depth, stretch_depth, 2):
check = 0
for i in xrange(1, iterations + 1):
check += check_tree(make_tree(i, depth)) + check_tree(make_tree(-i, depth))
print "%d\t trees of depth %d\t check:" % (iterations * 2, depth), check
iterations /= 4
print "long lived tree of depth %d\t check:" % max_depth, check_tree(long_lived_tree)
print("elapsed: " + str(time.clock() - start))

51
benchmark/binary_trees.rb Normal file
View File

@ -0,0 +1,51 @@
# The Computer Language Shootout Benchmarks
# http://shootout.alioth.debian.org
#
# contributed by Jesse Millikan
# Modified by Wesley Moxam
def item_check(left, item, right)
return item if left.nil?
item + item_check(*left) - item_check(*right)
end
def bottom_up_tree(item, depth)
return [nil, item, nil] unless depth > 0
item_item = 2 * item
depth -= 1
[bottom_up_tree(item_item - 1, depth), item, bottom_up_tree(item_item, depth)]
end
max_depth = 14
min_depth = 4
max_depth = min_depth + 2 if min_depth + 2 > max_depth
stretch_depth = max_depth + 1
stretch_tree = bottom_up_tree(0, stretch_depth)
start = Time.now
puts "stretch tree of depth #{stretch_depth}\t check: #{item_check(*stretch_tree)}"
stretch_tree = nil
long_lived_tree = bottom_up_tree(0, max_depth)
min_depth.step(max_depth + 1, 2) do |depth|
iterations = 2**(max_depth - depth + min_depth)
check = 0
for i in 1..iterations
temp_tree = bottom_up_tree(i, depth)
check += item_check(*temp_tree)
temp_tree = bottom_up_tree(-i, depth)
check += item_check(*temp_tree)
end
puts "#{iterations * 2}\t trees of depth #{depth}\t check: #{check}"
end
puts "long lived tree of depth #{max_depth}\t check: #{item_check(*long_lived_tree)}"
puts "elapsed: " + (Time.now - start).to_s

View File

@ -0,0 +1,60 @@
// Ported from the Python version.
class Tree {
this new(item, depth) {
_item = item
if (depth > 0) {
var item2 = item + item
depth = depth - 1
_left = Tree.new(item2 - 1, depth)
_right = Tree.new(item2, depth)
}
}
check {
if (_left == null) {
_item
} else {
_item + _left.check - _right.check
}
}
}
var minDepth = 4
var maxDepth = 14
var stretchDepth = maxDepth + 1
var start = OS.clock
io.write("stretch tree of depth " + stretchDepth.toString + "\t check: " +
Tree.new(0, stretchDepth).check.toString)
var longLivedTree = Tree.new(0, maxDepth)
// iterations = 2 ** maxDepth
var iterations = 1
var d = 0
while (d < maxDepth) {
iterations = iterations * 2
d = d + 1
}
var depth = minDepth
while (depth < stretchDepth) {
var check = 0
var i = 1
while (i < iterations + 1) {
check = check + Tree.new(i, depth).check + Tree.new(-i, depth).check
i = i + 1
}
io.write((iterations * 2).toString + "\t trees of depth " + depth.toString +
"\t check: " + check.toString)
iterations = iterations / 4
depth = depth + 2
}
io.write("long lived tree of depth " + maxDepth.toString + "\t check: " +
longLivedTree.check.toString)
io.write("elapsed: " + (OS.clock - start).toString)

View File

@ -1,20 +1,32 @@
#!/usr/bin/python
import math
import os
import re
import subprocess
import sys
FIB_OUTPUT_PATTERN = re.compile(r"""832040
832040
832040
832040
832040
elapsed: (\d+\.\d+)""", re.MULTILINE)
BENCHMARKS = []
BENCHMARKS = [
("fib", FIB_OUTPUT_PATTERN)
]
def BENCHMARK(name, pattern):
BENCHMARKS.append((name, re.compile(pattern, re.MULTILINE)))
BENCHMARK("binary_trees", """stretch tree of depth 15\t check: -1
32768\t trees of depth 4\t check: -32768
8192\t trees of depth 6\t check: -8192
2048\t trees of depth 8\t check: -2048
512\t trees of depth 10\t check: -512
128\t trees of depth 12\t check: -128
32\t trees of depth 14\t check: -32
long lived tree of depth 14\t check: -1
elapsed: (\\d+\\.\\d+)""")
BENCHMARK("fib", r"""832040
832040
832040
832040
832040
elapsed: (\d+\.\d+)""")
LANGUAGES = [
("wren", "../build/Release/wren", ".wren"),
@ -47,21 +59,26 @@ def run_benchmark_once(benchmark, language):
if match:
return float(match.group(1))
else:
print "Incorrect output:"
print out
return None
def run_benchmark(benchmark, language):
print "{0} - {1:10s}".format(benchmark[0], language[0]),
if not os.path.exists(benchmark[0] + language[2]):
print "No implementation for this language"
return
times = []
for i in range(0, NUM_TRIALS):
times.append(run_benchmark_once(benchmark, language))
time = run_benchmark_once(benchmark, language)
if not time:
return
times.append(time)
sys.stdout.write(".")
if None in times:
print "error"
return
times.sort()
stats = calc_stats(times)
print " mean: {0:.4f} median: {1:.4f} std_dev: {2:.4f}".format(
@ -78,12 +95,12 @@ def graph_results():
time = max(result[1])
if time > highest: highest = time
print "{0:15s} 0.0 {1:76.4f}".format("", highest)
print "{0:24s} 0.0 {1:76.4f}".format("", highest)
for result in results:
line = ["-"] * 80
for time in result[1]:
line[int(time / highest * 79)] = "O"
print "{0:15s} {1}".format(result[0], "".join(line))
print "{0:24s} {1}".format(result[0], "".join(line))
for benchmark in BENCHMARKS:
for language in LANGUAGES:

View File

@ -401,12 +401,13 @@ static void readString(Parser* parser)
case '"': addStringChar(parser, '"'); break;
case '\\': addStringChar(parser, '\\'); break;
case 'n': addStringChar(parser, '\n'); break;
case 't': addStringChar(parser, '\t'); break;
default:
// TODO(bob): Emit error token.
break;
}
// TODO(bob): Other escapes (/t, /r, etc.), Unicode escape sequences.
// TODO(bob): Other escapes (\r, etc.), Unicode escape sequences.
}
else
{