Commits

David Schneider committed 27ea547

implement statistics builtin with support for runtime and walltime base on the python time module

Comments (0)

Files changed (3)

prolog/builtin/__init__.py

 import prolog.builtin.formatting
 import prolog.builtin.metacall
 #import prolog.builtin.parseraccess
+import prolog.builtin.statistics
 import prolog.builtin.source
 import prolog.builtin.termconstruction
 import prolog.builtin.unify

prolog/builtin/statistics.py

+import prolog
+import py
+import time
+from prolog.interpreter import helper, term, error
+from prolog.builtin.register import expose_builtin
+
+
+wall_start = time.time()
+# TODO: make this continuation based and return all statistics
+@expose_builtin("statistics", unwrap_spec=["atom", "obj"])
+def impl_statistics(engine, heap, stat_name, value):
+    if stat_name == 'runtime':        
+        t = [clock_time(), clocktime_since_last_call()]
+    if stat_name == 'walltime':
+        t = [walltime(), walltime_since_last_call()]
+    l = map(term.Number, t)
+    helper.wrap_list(l).unify(value, heap)
+
+clock_now = None
+def clock_time():
+    prolog.builtin.statistics.clock_now = int(time.clock()*1000)
+    return prolog.builtin.statistics.clock_now
+    
+clock_last = 0
+def clocktime_since_last_call():
+    prolog.builtin.statistics.clock_last = prolog.builtin.statistics.clock_now - prolog.builtin.statistics.clock_last
+    return prolog.builtin.statistics.clock_last
+    
+wall_now = 0
+def walltime():
+    prolog.builtin.statistics.wall_now = int(time.time()*1000)
+    return prolog.builtin.statistics.wall_now    
+
+wall_last = 0
+def walltime_since_last_call():
+    prolog.builtin.statistics.wall_last = prolog.builtin.statistics.wall_now - prolog.builtin.statistics.wall_last
+    return prolog.builtin.statistics.wall_last
+    
+def reset_clocks():
+    prolog.builtin.statistics.clock_last = prolog.builtin.statistics.clock_now = 0
+    prolog.builtin.statistics.wall_last = prolog.builtin.statistics.wall_now = 0

prolog/builtin/test/test_statistics.py

+import py
+import time
+from prolog.interpreter.continuation import Engine
+from prolog.interpreter.test.tool import collect_all, assert_false, assert_true
+from prolog.builtin.statistics import clock_time, reset_clocks, walltime
+
+e = Engine()
+def test_statistics():
+    assert_true("statistics(runtime, X).", e)
+    
+def test_statistics_builds_list():
+    assert_true('statistics(runtime, [A,B]), number(A), number(B).')
+    
+def test_statistics_runtime_total():
+    reset_clocks()
+    # first call returns total runtime in both list items
+    clock = clock_time()
+    vars = assert_true("statistics(runtime, [A,B]).")
+    assert vars['A'].num == vars['B'].num
+    assert clock <= vars['A'].num
+    
+def test_statistics_runtime_since_last_call():
+    reset_clocks()
+    # succesive call return total runtime and time since last call
+    clock = clock_time()
+    vars = assert_true("statistics(runtime, _), statistics(runtime, [A,B]).")
+    assert vars['A'] != vars['B']
+    assert clock <= vars['A'].num
+    assert vars['B'].num <= clock
+    
+def test_statistics_walltime_total():
+    reset_clocks()
+    # first call returns total runtime in both list items
+    clock = walltime()
+    vars = assert_true("statistics(walltime, [A,B]).")
+    assert vars['A'].num == vars['B'].num
+    assert clock <= vars['A'].num
+
+def test_statistics_walltime_since_last_call():
+    reset_clocks()
+    # succesive call return total runtime and time since last call
+    clock = walltime()
+    vars = assert_true("statistics(walltime, _), statistics(walltime, [A,B]).")
+    assert vars['A'] != vars['B']
+    assert clock <= vars['A'].num
+    assert vars['B'].num <= clock