Range operators!

Added ".." and "..." infix operators. Num implements them to
return Range objects. Those in turn implement the iterator
protocol, so now numeric for loops are easy:

    for (i in 1..10) { ... }

I also cleaned up the Wren benchmarks to use this.

In the process, I discovered the method_call benchmark really
just showed loop peformance, so I unrolled the loops in all of
the languages to stress method calls.
This commit is contained in:
Bob Nystrom
2013-12-25 15:01:45 -08:00
parent 2b65e47747
commit 507e89d3b3
12 changed files with 209 additions and 44 deletions
+19
View File
@@ -0,0 +1,19 @@
The benchmarks in here attempt to faithfully implement the exact same algorithm in a few different languages. We're using Lua, Python, and Ruby for comparison here because those are all in Wren's ballpark: dynamically-typed, object-oriented, bytecode-compiled.
A bit about each benchmark:
## binary_trees
This benchmark stress object creation and garbage collection. It builds a few big, deeply nested binaries and then traverses them.
## fib
This is just a simple naïve Fibonacci number calculator. It was the first benchmark I wrote when Wren supported little more than function calls and arithmetic. It isn't particularly representative of real-world code, but it does stress function call and arithmetic.
## for
This microbenchmark just tests the performance of for loops. Not too useful, but i used it when implementing `for` in Wren to make sure it wasn't too far off the mark.
## method_call
This is the most useful benchmark: it tests dynamic dispatch and polymorphism. You'll note that the main iteration loop is unrolled in all of the implementations. This is to ensure that the loop overhead itself doesn't dwarf the method call time.
+1 -3
View File
@@ -33,10 +33,8 @@ var longLivedTree = new Tree(0, maxDepth)
// iterations = 2 ** maxDepth
var iterations = 1
var d = 0
while (d < maxDepth) {
for (d in 0...maxDepth) {
iterations = iterations * 2
d = d + 1
}
var depth = minDepth
+1 -3
View File
@@ -7,9 +7,7 @@ var fib = fn(n) {
}
var start = OS.clock
var i = 0
while (i < 5) {
for (i in 1..5) {
IO.write(fib.call(28))
i = i + 1
}
IO.write("elapsed: " + (OS.clock - start).toString)
+1 -7
View File
@@ -1,12 +1,6 @@
var list = []
{
var i = 0
while (i < 2000000) {
list.add(i)
i = i + 1
}
}
for (i in 0...2000000) list.add(i)
var start = OS.clock
var sum = 0
+19 -1
View File
@@ -54,12 +54,21 @@ end
function main ()
local start = os.clock()
local N = 1000000
local N = 100000
local val = 1
local toggle = Toggle:new(val)
for i=1,N do
val = toggle:activate():value()
val = toggle:activate():value()
val = toggle:activate():value()
val = toggle:activate():value()
val = toggle:activate():value()
val = toggle:activate():value()
val = toggle:activate():value()
val = toggle:activate():value()
val = toggle:activate():value()
val = toggle:activate():value()
end
print(val and "true" or "false")
@@ -67,6 +76,15 @@ function main ()
local ntoggle = NthToggle:new(val, 3)
for i=1,N do
val = ntoggle:activate():value()
val = ntoggle:activate():value()
val = ntoggle:activate():value()
val = ntoggle:activate():value()
val = ntoggle:activate():value()
val = ntoggle:activate():value()
val = ntoggle:activate():value()
val = ntoggle:activate():value()
val = ntoggle:activate():value()
val = ntoggle:activate():value()
end
print(val and "true" or "false")
io.write(string.format("elapsed: %.8f\n", os.clock() - start))
+19 -1
View File
@@ -29,12 +29,21 @@ class NthToggle(Toggle):
def main():
start = time.clock()
NUM = 1000000
NUM = 100000
val = 1
toggle = Toggle(val)
for i in xrange(0,NUM):
val = toggle.activate().value()
val = toggle.activate().value()
val = toggle.activate().value()
val = toggle.activate().value()
val = toggle.activate().value()
val = toggle.activate().value()
val = toggle.activate().value()
val = toggle.activate().value()
val = toggle.activate().value()
val = toggle.activate().value()
if val:
print "true"
else:
@@ -44,6 +53,15 @@ def main():
ntoggle = NthToggle(val, 3)
for i in xrange(0,NUM):
val = ntoggle.activate().value()
val = ntoggle.activate().value()
val = ntoggle.activate().value()
val = ntoggle.activate().value()
val = ntoggle.activate().value()
val = ntoggle.activate().value()
val = ntoggle.activate().value()
val = ntoggle.activate().value()
val = ntoggle.activate().value()
val = ntoggle.activate().value()
if val:
print "true"
else:
+19 -1
View File
@@ -39,12 +39,21 @@ end
def main()
start = Time.now
n = 1000000
n = 100000
val = 1
toggle = Toggle.new(val)
n.times do
val = toggle.activate().value()
val = toggle.activate().value()
val = toggle.activate().value()
val = toggle.activate().value()
val = toggle.activate().value()
val = toggle.activate().value()
val = toggle.activate().value()
val = toggle.activate().value()
val = toggle.activate().value()
val = toggle.activate().value()
end
if val then puts "true" else puts "false" end
@@ -52,6 +61,15 @@ def main()
ntoggle = NthToggle.new(val, 3)
n.times do
val = ntoggle.activate().value()
val = ntoggle.activate().value()
val = ntoggle.activate().value()
val = ntoggle.activate().value()
val = ntoggle.activate().value()
val = ntoggle.activate().value()
val = ntoggle.activate().value()
val = ntoggle.activate().value()
val = ntoggle.activate().value()
val = ntoggle.activate().value()
end
if val then puts "true" else puts "false" end
+21 -7
View File
@@ -29,14 +29,21 @@ class NthToggle is Toggle {
}
var start = OS.clock
var n = 1000000
var i = 0
var n = 100000
var val = true
var toggle = new Toggle(val)
while (i < n) {
for (i in 0...n) {
val = toggle.activate.value
val = toggle.activate.value
val = toggle.activate.value
val = toggle.activate.value
val = toggle.activate.value
val = toggle.activate.value
val = toggle.activate.value
val = toggle.activate.value
val = toggle.activate.value
val = toggle.activate.value
i = i + 1
}
IO.write(toggle.value)
@@ -44,10 +51,17 @@ IO.write(toggle.value)
val = true
var ntoggle = new NthToggle(val, 3)
i = 0
while (i < n) {
for (i in 0...n) {
val = ntoggle.activate.value
val = ntoggle.activate.value
val = ntoggle.activate.value
val = ntoggle.activate.value
val = ntoggle.activate.value
val = ntoggle.activate.value
val = ntoggle.activate.value
val = ntoggle.activate.value
val = ntoggle.activate.value
val = ntoggle.activate.value
i = i + 1
}
IO.write(ntoggle.value)