lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


I came across the sources to an implementation of Datalog I wrote in
OCaml and placed them on GitHub at
<https://github.com/ramsdell/ocaml-datalog>.  The algorithm is
identical to the one I wrote in Lua, in fact, the OCaml version
preceded the Lua version.  I used a test suite created by Simon
Cruanes and compared the elapse time and the max resident memory size
of the two programs.  Lua was a bit slower and used more memory.  Not
unexpected I suppose.

John

---------------------------------------------------------

	Lua vs. OCaml Datalog Performance

	Elapsed Time	Max Resident

induction 200
Lua	0.25 Sec	3916 KB
OCaml	0.03 Sec	3884 KB

induction 500
Lua	1.42 Sec	8328 KB
OCaml	0.20 Sec	4800 KB

induction 1000
Lua	5.65 Sec	14440 KB
OCaml	0.77 Sec	6808 KB

induction 1500
Lua	14.26 Sec	20668 KB
OCaml	1.16 Sec	8844 KB

reachable 200
Lua	1.05 Sec	40316 KB
OCaml	0.25 Sec	15608 KB

reachable 500
Lua	7.14 Sec	229216 KB
OCaml	3.37 Sec	81852 KB

reachable 1000
Lua	40.16 Sec	972408 KB
OCaml	25.36 Sec	323516 KB

reachable 1500
Lua	97.66 Sec	2169556 KB
OCaml	61.68 Sec	681012 KB
---------------------------------------------------------
#! /bin/sh

# Compares the performance of Datalog in Lua and Datalog in OCaml

# Based on a test suite by Simon Cruanes <https://github.com/c-cube>

# Be sure to make OCaml Datalog with "make native-code"

# Location of Datalog in Lua
DATALOG=${1:-datalog}

# Sizes of test cases
TESTS="200 500 1000 1500"

# Time format
export TIME="\t%e Sec\t%M KB"

# INDUCTION TEST

# Generate a recursive induction example of given size; it makes rules
# p(n+1) if p(n),q(n+1)
# and
# q(n+1) if p(n), q(n)
# for n ranging in [0...size], and adds facts p(0) and q(0)

induction() {
    local n=${1:-10}
    echo '% Problem size: '$n
    for ((i=0; i<$n; i++))
    do
	let j=$i+1
	echo 'p('$j') :- p('$i'), q('$j').'
	echo 'q('$j') :- p('$i'), q('$i').'
    done
    echo 'p(0).'
    echo 'q(0).'
    echo 'p(X)?'
}

# REACHABLE TEST

# Generate a graph example of given size. It produces a cyclic graph
# with vertices in [0...size-1] and edges from i to i+1 mod size. The
# single rule computes a transitive closure of the graph, the
# predicate reachable() describes a clique of size size.

reachable() {
    local n=${1:-10}
    echo '% Problem size: '$n
    echo 'reachable(X,Y) :- edge(X,Y).'
    echo 'reachable(X,Y) :- edge(X,Z), reachable(Z,Y).'
    for ((i=0; i<$n; i++))
    do
	let j=$i+1
	echo 'edge('$i', '$j').'
    done
    echo 'edge('$n', 0).'
    echo 'reachable(X,Y)?'
}

printf "\tLua vs. OCaml Datalog Performance\n\n"
printf "\tElapsed Time\tMax Resident\n"

for i in ${TESTS}
do
    echo
    echo induction $i
    echo -n Lua
    induction $i | /usr/bin/time $DATALOG -o /dev/null
    echo -n OCaml
    induction $i | /usr/bin/time ./datalog -o /dev/null
done

for i in ${TESTS}
do
    echo
    echo reachable $i
    echo -n Lua
    reachable $i | /usr/bin/time $DATALOG -o /dev/null
    echo -n OCaml
    reachable $i | /usr/bin/time ./datalog -o /dev/null
done