From: fennecdjay Date: Fri, 28 Jun 2019 10:14:05 +0000 (+0200) Subject: :book: Benchmarks X-Git-Tag: nightly~2384^2~1 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=397b972807c939db6becda7be9e67966326b4966;p=gwion.git :book: Benchmarks --- diff --git a/.gitignore b/.gitignore index 3b548b3c..d741608c 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ gwion config.mk include/generated.h .desk +mkdocs.yml +*.a diff --git a/docs.mk b/docs.mk index b767302d..af87eff9 100644 --- a/docs.mk +++ b/docs.mk @@ -42,18 +42,18 @@ doc-deploy: $(md_list) .SUFFIXES: .gw .test .gw.test: - @${VALGRIND} ${VALGRIND_OPT} gwion $< &> log + @${VALGRIND} ${VALGRIND_OPT} gwion $< 2>&1 > log @[ -t 1 ] && $(call _interm) || $(call _noterm) define _test_check for a in $(CONTAINS); do grep "$$a" log >/dev/null; done && valgrind_parse vlog endef -_interm_status=echo -e "$(INTERM_OK)" || echo -e "$(INTERM_NOT_OK)" +_interm_status=printf "$(INTERM_OK)\n" || printf "$(INTERM_NOT_OK)\n" _interm=(cat log; $(call _test_check) && $(call _interm_status)) _noterm_log=sed 's/$$/\/' log -_noterm_status=echo -e "$(NOTERM_OK)" || echo -e "$(NOTERM_NOT_OK)" +_noterm_status=printf "$(NOTERM_OK)\n" || printf "$(NOTERM_NOT_OK)\n" _noterm_test=$(call _test_check) && $(call _noterm_status) _noterm_header=echo '

' _noterm_footer=echo '

' diff --git a/docs/01_Overview/declaration.mdr b/docs/01_Overview/declaration.mdr index e359c6a3..9afb021c 100644 --- a/docs/01_Overview/declaration.mdr +++ b/docs/01_Overview/declaration.mdr @@ -19,15 +19,16 @@ Object @ref; new Object @=> ref; <<<"But now it does: ", ref>>>; @``` -@exec gwion decl1.gw 2>&1 +@exec make decl1.test ## Arrays ### array as refs + @``` decl2.gw int ref[]; <<>>; new int[2] @=> ref; <<>>; @``` -@exec gwion decl2.gw 2>&1 +@exec make decl2.test diff --git a/docs/Benchmarks.mdr b/docs/Benchmarks.mdr new file mode 100644 index 00000000..ef684742 --- /dev/null +++ b/docs/Benchmarks.mdr @@ -0,0 +1,86 @@ +# Benchmarks + +We'll need a bash script + + + +### and a gnuplot script + + + +## Show the results +Then just run it +@exec bash benchmark.sh; rm bench.plot benchmark.sh diff --git a/docs/WIP_Driver.mdr b/docs/Extending/WIP_Driver.mdr similarity index 100% rename from docs/WIP_Driver.mdr rename to docs/Extending/WIP_Driver.mdr diff --git a/docs/WIP_Plugins.mdr b/docs/Extending/WIP_Plugins.mdr similarity index 100% rename from docs/WIP_Plugins.mdr rename to docs/Extending/WIP_Plugins.mdr diff --git a/docs/Functions/function.mdr b/docs/Functions/function.mdr index 5a656e45..f92a174f 100644 --- a/docs/Functions/function.mdr +++ b/docs/Functions/function.mdr @@ -1,7 +1,8 @@ # Functions ## a simple (commented example) -@```function0.gw + +@``` function0.gw // declare function 'test_function' // with return type int // taking an int as argument diff --git a/docs/Make.mdr b/docs/Make.mdr index 56000b97..45a5452d 100644 --- a/docs/Make.mdr +++ b/docs/Make.mdr @@ -1,4 +1,4 @@ -# Gwion's Makefile +# Makefile ## Basic operations diff --git a/docs/assets/benchmark/binary_trees.dat b/docs/assets/benchmark/binary_trees.dat new file mode 100644 index 00000000..a8dc8e81 --- /dev/null +++ b/docs/assets/benchmark/binary_trees.dat @@ -0,0 +1,3 @@ +gwion 0.244813625 0.33 +wren 0.358684268 1.43 +lua5.3 0.621848489 5.69 diff --git a/docs/assets/benchmark/binary_trees.png b/docs/assets/benchmark/binary_trees.png new file mode 100644 index 00000000..ea48d1cc Binary files /dev/null and b/docs/assets/benchmark/binary_trees.png differ diff --git a/docs/assets/doc.css b/docs/assets/doc.css new file mode 100644 index 00000000..692967e8 --- /dev/null +++ b/docs/assets/doc.css @@ -0,0 +1,7 @@ +li + .lev2 { + display: none; +} + +li:focus-within + .lev2 { + display: block; +} diff --git a/help/benchmark.sh b/help/benchmark.sh deleted file mode 100644 index 80bc7799..00000000 --- a/help/benchmark.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh -#run benchmarks and make plots -: "${repeats:=10}" - -fib_test() { -# echo "\"$1\"" "$(perf stat -r"$repeats" "$1" "fib_recurs.$2" 2>&1 | grep "time elapsed" | cut -d s -f 1 | sed 's/+-//' | sed 's/,/./g')" - printf "$(perf stat -r"$repeats" "$1" "fib_recurs.$2" 2>&1 | grep "time elapsed" | cut -d s -f 1 | sed 's/+-//' | sed 's/,/./g')" -} - -cd ~/fib_recurs/ || exit 1 -printf "\"fib recurs\" " -fib_test gwion gw -fib_test lua lua -fib_test wren wren -#fib_test chuck ck -#fib_test ruby rb -#fib_test perl pl -#fib_test python2 py -#fib_test python3 py -#fib_test runhaskell hs diff --git a/help/doc-config.sh b/help/doc-config.sh index 4fccb6af..6f197cec 100644 --- a/help/doc-config.sh +++ b/help/doc-config.sh @@ -1,15 +1,17 @@ title() { TMP=$(head -n 1 $1) - echo ${TMP:2} + sed "s/'/\'/" <<< "${TMP:2}" } list_dir() { + [[ "$1" == */"assets" ]] && return for a in $1/* do - if [ -d "$a" ] - then echo "$2- '$(basename $a | sed 's/[0-9][0-9]_//' | sed 's/_/ /g' | sed 's/-/ /g')':"; list_dir $a "$2 " - else echo "$a" | grep "\.md$" >/dev/null && echo "$2- $(title $a): ${a:5}" - fi + if [ -d "$a" ] + then [[ "$a" == */"assets" ]] || + echo "$2- '$(basename $a | sed 's/[0-9][0-9]_//' | sed 's/_/ /g' | sed 's/-/ /g')':"; list_dir "$a" "$2 " + else echo "$a" | grep "\.md$" >/dev/null && echo "$2- '$(title $a)': ${a:5}" + fi done } diff --git a/tests/benchmark/binary_trees.dart b/tests/benchmark/binary_trees.dart new file mode 100644 index 00000000..f7d52d5f --- /dev/null +++ b/tests/benchmark/binary_trees.dart @@ -0,0 +1,56 @@ +// Ported from the Wren version. + +class Tree { + var _item; + var _left; + var _right; + + Tree(item, depth) { + _item = item; + if (depth > 0) { + var item2 = item + item; + depth--; + _left = new Tree(item2 - 1, depth); + _right = new Tree(item2, depth); + } + } + + get check { + if (_left == null) { + return _item; + } + + return _item + _left.check - _right.check; + } +} + +main() { + var minDepth = 4; + var maxDepth = 12; + var stretchDepth = maxDepth + 1; + + print("stretch tree of depth ${stretchDepth} check: " + "${new Tree(0, stretchDepth).check}"); + + var longLivedTree = new Tree(0, maxDepth); + + // iterations = 2 ** maxDepth + var iterations = 1; + for (var d = 0; d < maxDepth; d++) { + iterations = iterations * 2; + } + + var depth = minDepth; + while (depth < stretchDepth) { + var check = 0; + for (var i = 1; i <= iterations; i++) { + check += new Tree(i, depth).check + new Tree(-i, depth).check; + } + + print("${iterations * 2} trees of depth ${depth} check: ${check}"); + iterations ~/= 4; + depth += 2; + } + + print("long lived tree of depth ${maxDepth} check: ${longLivedTree.check}"); +} diff --git a/tests/benchmark/binary_trees.gw b/tests/benchmark/binary_trees.gw new file mode 100644 index 00000000..7d8c8e30 --- /dev/null +++ b/tests/benchmark/binary_trees.gw @@ -0,0 +1,51 @@ +// Ported from the Wren version. + +class Tree { + int item; + Tree @left, right; + + fun static Tree new_Tree(int it, int depth) { + Tree t; + it => t.item; + if (depth > 0) { + it + it => int item2; + --depth; + Tree.new_Tree(item2 - 1, depth) @=> t.left; + Tree.new_Tree(item2, depth) @=> t.right; + } + return t; + } + + fun int check() { + if (!left) + return item; + return item + left.check() - right.check(); + } +} + +4 => int minDepth; +12 => int maxDepth; +maxDepth + 1 => int stretchDepth; + +<<<"stretch tree of depth ", stretchDepth, " check: ", + Tree.new_Tree(0, stretchDepth).check()>>>; + +Tree.new_Tree(0, maxDepth) @=> Tree@ longLivedTree; + +// iterations = 2 ** maxDepth +1 => int iterations; +for (int d; d < maxDepth; ++d) + 2 *=> iterations; + +minDepth => int depth; +while (depth < stretchDepth) { + int check; + for (int i; i < iterations; ++i) + Tree.new_Tree(i, depth).check() + Tree.new_Tree(-i, depth).check() +=> check; + + <<>>; + 4 /=> iterations; + 2 +=> depth; +} + +<<<"long lived tree of depth ", maxDepth, " check: ", longLivedTree.check()>>>; diff --git a/tests/benchmark/binary_trees.lua b/tests/benchmark/binary_trees.lua new file mode 100644 index 00000000..e690c270 --- /dev/null +++ b/tests/benchmark/binary_trees.lua @@ -0,0 +1,50 @@ +-- 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 = 12 +local mindepth = 4 +local maxdepth = mindepth + 2 +if maxdepth < N then maxdepth = N end + +do + local stretchdepth = maxdepth + 1 + local stretchtree = BottomUpTree(0, stretchdepth) + io.write(string.format("stretch tree of depth %d 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 trees of depth %d check: %d\n", + iterations*2, depth, check)) +end + +io.write(string.format("long lived tree of depth %d check: %d\n", + maxdepth, ItemCheck(longlivedtree))) diff --git a/tests/benchmark/binary_trees.py b/tests/benchmark/binary_trees.py new file mode 100644 index 00000000..eb3a9b9a --- /dev/null +++ b/tests/benchmark/binary_trees.py @@ -0,0 +1,46 @@ +# The Computer Language Benchmarks Game +# http://shootout.alioth.debian.org/ +# +# contributed by Antoine Pitrou +# modified by Dominique Wahli +# modified by Heinrich Acker +from __future__ import print_function + +import time + +# Map "range" to an efficient range in both Python 2 and 3. +try: + range = xrange +except NameError: + pass + +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(node): + item, left, right = node + if not left: return item + return item + check_tree(left) - check_tree(right) + +min_depth = 4 +max_depth = 12 +stretch_depth = max_depth + 1 + +print("stretch tree of depth %d 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 range(min_depth, stretch_depth, 2): + + check = 0 + for i in range(1, iterations + 1): + check += check_tree(make_tree(i, depth)) + check_tree(make_tree(-i, depth)) + + print("%d trees of depth %d check:" % (iterations * 2, depth), check) + iterations //= 4 + +print("long lived tree of depth %d check:" % max_depth, check_tree(long_lived_tree)) diff --git a/tests/benchmark/binary_trees.rb b/tests/benchmark/binary_trees.rb new file mode 100644 index 00000000..2118083c --- /dev/null +++ b/tests/benchmark/binary_trees.rb @@ -0,0 +1,49 @@ +# 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 = 12 +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) + +puts "stretch tree of depth #{stretch_depth} 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} trees of depth #{depth} check: #{check}" +end + +puts "long lived tree of depth #{max_depth} check: #{item_check(*long_lived_tree)}" diff --git a/tests/benchmark/binary_trees.wren b/tests/benchmark/binary_trees.wren new file mode 100644 index 00000000..2393462b --- /dev/null +++ b/tests/benchmark/binary_trees.wren @@ -0,0 +1,51 @@ +// Ported from the Python version. + +class Tree { + construct 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) { + return _item + } + + return _item + _left.check - _right.check + } +} + +var minDepth = 4 +var maxDepth = 12 +var stretchDepth = maxDepth + 1 + +System.print("stretch tree of depth %(stretchDepth) check: " + + "%(Tree.new(0, stretchDepth).check)") + +var longLivedTree = Tree.new(0, maxDepth) + +// iterations = 2 ** maxDepth +var iterations = 1 +for (d in 0...maxDepth) { + iterations = iterations * 2 +} + +var depth = minDepth +while (depth < stretchDepth) { + var check = 0 + for (i in 1..iterations) { + check = check + Tree.new(i, depth).check + Tree.new(-i, depth).check + } + + System.print("%(iterations * 2) trees of depth %(depth) check: %(check)") + iterations = iterations / 4 + depth = depth + 2 +} + +System.print( + "long lived tree of depth %(maxDepth) check: %(longLivedTree.check)") diff --git a/tests/benchmark/binary_trees_gc.wren b/tests/benchmark/binary_trees_gc.wren new file mode 100644 index 00000000..803202ec --- /dev/null +++ b/tests/benchmark/binary_trees_gc.wren @@ -0,0 +1,55 @@ +// Ported from the Python version. + +class Tree { + construct 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) { + return _item + } + + return _item + _left.check - _right.check + } +} + +var minDepth = 4 +var maxDepth = 12 +var stretchDepth = maxDepth + 1 + +System.print("stretch tree of depth %(stretchDepth) check: " + + "%(Tree.new(0, stretchDepth).check)") +for (i in 1...1000) System.gc() + +var longLivedTree = Tree.new(0, maxDepth) + +// iterations = 2 ** maxDepth +var iterations = 1 +for (d in 0...maxDepth) { + iterations = iterations * 2 +} + +var depth = minDepth +while (depth < stretchDepth) { + var check = 0 + for (i in 1..iterations) { + check = check + Tree.new(i, depth).check + Tree.new(-i, depth).check + } + + System.print("%(iterations * 2) trees of depth %(depth) check: %(check)") + for (i in 1...1000) System.gc() + + iterations = iterations / 4 + depth = depth + 2 +} + +System.print( + "long lived tree of depth %(maxDepth) check: %(longLivedTree.check)") +for (i in 1...1000) System.gc()