Logtalk 2.30.1 files.

git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@1903 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
pmoura
2007-06-12 10:39:47 +00:00
parent 84f478c301
commit 6b4bde14e1
475 changed files with 6213 additions and 6424 deletions

View File

@@ -1,9 +1,9 @@
=================================================================
Logtalk - Object oriented extension to Prolog
Release 2.29.5
================================================================
Logtalk - Open source object-oriented logic programming language
Release 2.30.1
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
=================================================================
================================================================
To load this example and for sample queries, please see the SCRIPT file.
@@ -13,10 +13,20 @@ sending performance with direct predicates calls in plain Prolog.
These benchmarks may also be used for comparing Logtalk message sending
performance across Prolog compilers.
This example is made of five source files:
This example is made of four loader files and five source files:
benchmark.lgt
contains the benchmark predicates
loader_events.lgt
loads all source files with event support turned on
loader_no_events.lgt
loads all source files with event support turned off
loader_static_binding.lgt
loads all source files with event support turned off and using
static binding
loader.lgt
the same as the loader_static_binding.lgt file
benchmarks.lgt
contains the benchmark goals and testing predicates
plain.lgt
contains a definition for a list length predicate and a predicate
for testing performance of the built-in predicates assertz/1 and
@@ -24,37 +34,50 @@ This example is made of five source files:
module.pl (not loaded by default; see below)
contains the same definition of a list length predicate
encapsulated in a module
object.lgt
contains the same definition of a list length predicate
encapsulated in an object
objects.lgt
contains an object encapsulating the same definition of a list
length predicate, plus two descendant objects to simulate a small
hierarchy (used for testing calls to imported category predicates)
database.lgt
contains predicates for testing the performance of the built-in
database methods assertz/1 and retract/1
category.lgt
contains a single predicate used when comparing performance of
calls to imported category predicates using direct calls and using
messages to "self"
You may have noticed above that the benchmark predicates and the predicates
for plain Prolog testing are both encapsulated in Logtalk source files. The
Logtalk compiler just copies the plain Prolog code to the generated Prolog
files. The reason for using the .lgt extension for these files is just to
make it possible to load all the example code using a single call to the
logtalk_load/1 predicate.
files. The reason for using the .lgt extension for these files is simply to
make it possible to load all the example code using calls to the predicates
logtalk_load/1-2.
By default, the benchmark tests on the SCRIPT file use a list of 30 elements
as an argument to the list length predicates. Increasing the list length
leads to decreasing performance differences between plain Prolog and Logtalk
as the list length computation time far outweighs the overhead of the message
sending mechanism. Likewise, decreasing the list length leads to increasing
performance differences between plain Prolog and Logtalk (up to the point you
will be measuring the Logtalk message sending mechanism overhead compared to
plain Prolog predicate calls). In real-life applications, only testing can
give you a balanced view on the trade-offs between plain Prolog performance
and Logtalk programming features.
By default, the benchmark tests on the SCRIPT file use a list of 20 elements
as an argument to the list length predicates. When dynamic binding is used,
increasing the list length leads to decreasing performance differences between
plain Prolog and Logtalk as the list length computation time far outweighs the
overhead of the message sending mechanism. Likewise, decreasing the list
length leads to increasing performance differences between plain Prolog and
Logtalk (up to the point you will be measuring the Logtalk message sending
mechanism overhead compared to plain Prolog predicate calls). In real-life
applications, only testing can give you a balanced view on the trade-offs
between plain Prolog performance and Logtalk programming features.
By default, the loader.lgt file used to load the example code does not load
the module.pl file. Edit this file if your Prolog compiler supports a module
By default, the loader files used to load the example code do not load the
module.pl file. Edit these files if your Prolog compiler supports a module
system and you want to run some comparative performance tests between plain
Prolog, Prolog modules, and Logtalk objects. Note that you may need to edit
the code on the module.pl file to make any necessary compatibility changes
for your Prolog compiler module system. For most Prolog module systems, the
performance of module calls is close or even identical to the performance of
plain Prolog calls, specially when using imported predicates as opposed to
using explicit module qualification.
plain Prolog calls when using imported predicates and implicit qualification.
When using explicit module qualification, performance can be significantly
worse.
When static binding is used, messages to objects are, whenever possible,
translated to direct predicate calls. Thus performance should be about the
same as in plain Prolog predicate calls. However, due to the overhead of
three extra arguments per object predicate (used for passing the execution
context), the performance of Logtalk optimized calls might be slightly
worse than the equivalent plain Prolog predicate calls.

View File

@@ -1,136 +1,69 @@
=================================================================
Logtalk - Object oriented extension to Prolog
Release 2.29.5
================================================================
Logtalk - Open source object-oriented logic programming language
Release 2.30.1
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
=================================================================
================================================================
% start by loading the example:
% start by loading the example by choosing one of the loader files
% (you must quit and restart Logtalk for each testing scenario):
| ?- logtalk_load(benchmarks(loader)).
% run benchmarks with event support turned on:
| ?- logtalk_load(benchmarks(loader_events)).
...
% run the default set of benchmark tests:
% run benchmarks with event support turned off:
| ?- benchmarks.
| ?- logtalk_load(benchmarks(loader_no_events)).
...
% or run specific benchmark tests individually as exemplified next...
% run benchmarks with event support turned off and using static binding:
| ?- logtalk_load(benchmarks(loader_static_binding)).
...
% call the predicate my_length/0 defined in the Prolog database:
% list all the benchmark tests:
| ?- generate_list(30, List), benchmark(my_length(List, _)).
| ?- benchmarks::benchmark(Id, Goal).
Goal = my_length([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19],_)
Id = s1 ? ;
Goal = object::length([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19],_)
Id = s2 ? ;
Goal = create_object(xpto,[],[],[]),abolish_object(xpto)
Id = d1 ? ;
Goal = plain_dyndb
Id = d2 ? ;
Goal = database::this_dyndb
Id = d3 ? ;
Goal = database::self_dyndb
Id = d4 ? ;
Goal = database::obj_dyndb
Id = d5
Number of repetitions: 100000
Loop time: 0.03 seconds
Goal time: 0.39 seconds
Average time per call: 3.6e-06 seconds
Number of calls per second: 277777.777777778
List = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29] ?
yes
% call the predicate object::length/2 from the top-level:
% run all the benchmark tests the default number of times:
| ?- generate_list(30, List), benchmark(object::length(List, _)).
Number of repetitions: 100000
Loop time: 0.04 seconds
Goal time: 0.79 seconds
Average time per call: 7.5e-06 seconds
Number of calls per second: 133333.333333333
List = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29] ?
yes
| ?- benchmarks::run.
...
% compiled call of the predicate object::length/2 (simulates message sending
% from a compiled object to another object; thus with no top-level overhead):
| ?- generate_list(30, List), benchmark('$lgt_send_to_object_nv'(object, length(List, _), user)).
Number of repetitions: 100000
Loop time: 0.0299999999999998 seconds
Goal time: 0.5 seconds
Average time per call: 4.70000000000001e-06 seconds
Number of calls per second: 212765.957446808
List = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29] ?
yes
% or run specific benchmark tests individually, for example:
% compiled call of the predicate object::length/2 (simulates message sending
% from a compiled object to another object with event-driven programming
% support switched off and with no top-level overhead):
| ?- generate_list(30, List), benchmark('$lgt_send_to_object_ne_nv'(object, length(List, _), user)).
Number of repetitions: 100000
Loop time: 0.0300000000000002 seconds
Goal time: 0.46 seconds
Average time per call: 4.3e-06 seconds
Number of calls per second: 232558.139534884
List = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29] ?
yes
% create and abolish an elementary dynamic object:
| ?- benchmark((create_object(xpto, [], [], []), abolish_object(xpto))).
Number of repetitions: 100000
Loop time: 0.0300000000000011 seconds
Goal time: 51.59 seconds
Average time per call: 0.0005156 seconds
Number of calls per second: 1939.48797517455
yes
% test assertz/1 and retract/1 performance in plain Prolog:
| ?- benchmark(db_test_plain).
Number of repetitions: 100000
Loop time: 0.0299999999999727 seconds
Goal time: 51.07 seconds
Average time per call: 0.0005104 seconds
Number of calls per second: 1959.24764890282
yes
% test assertz/1 and retract/1 performance on "this" database:
| ?- benchmark('$lgt_send_to_object_ne_nv'(database, db_test_this, user)).
Number of repetitions: 100000
Loop time: 0.0299999999999727 seconds
Goal time: 63.37 seconds
Average time per call: 0.0006334 seconds
Number of calls per second: 1578.78118092832
yes
% test assertz/1 and retract/1 performance on "self" database:
| ?- benchmark('$lgt_send_to_object_ne_nv'(database, db_test_self, user)).
Number of repetitions: 100000
Loop time: 0.0299999999999727 seconds
Goal time: 71.3499999999999 seconds
Average time per call: 0.000713199999999999 seconds
Number of calls per second: 1402.13123948402
yes
% test assertz/1 and retract/1 performance on another object database (using ::/2):
| ?- benchmark('$lgt_send_to_object_ne_nv'(database, db_test_obj, user)).
Number of repetitions: 100000
Loop time: 0.0299999999999727 seconds
Goal time: 68.97 seconds
Average time per call: 0.0006894 seconds
Number of calls per second: 1450.53669857847
yes
| ?- benchmarks::run(s1, 1000000).
...

View File

@@ -0,0 +1,155 @@
:- object(benchmarks).
:- info([
version is 3.0,
author is 'Paulo Moura',
date is 2007/06/11,
comment is 'Benchmark utility predicates and standard set of benchmarks.']).
:- public(run/0).
:- mode(run, one).
:- info(run/0, [
comment is 'Runs all benchmarks the default number of times.']).
:- public(run/1).
:- mode(run(+integer), one).
:- info(run/1, [
comment is 'Runs all benchmarks the specified number of times.',
argnames is ['N']]).
:- public(run/2).
:- mode(run(+atom, +integer), one).
:- info(run/2, [
comment is 'Runs a specific benchmark the specified number of times.',
argnames is ['Id', 'N']]).
:- public(benchmark/2).
:- mode(move(?atom, -callable), zero_or_more).
:- info(move/2, [
comment is 'Table of benchmark identifiers and benchmark goals.',
argnames is ['Id', 'Goal']]).
% run all benchmarks the default number of times:
run :-
run(1000000).
% run all benchmark tests N times:
run(N) :-
benchmark(Id, Goal),
run(Id, N, Looptime, Goaltime, Average, Speed),
report(Id, Goal, N, Looptime, Goaltime, Average, Speed),
fail.
run(_).
% run a specific benchmark test:
run(Id, N) :-
benchmark(Id, Goal),
run(Id, N, Looptime, Goaltime, Average, Speed),
report(Id, Goal, N, Looptime, Goaltime, Average, Speed).
run(Id, N, Looptime, Goaltime, Average, Speed) :-
{'$lgt_cpu_time'(Seconds1)}, % defined in the config files
do_benchmark(empty_loop, N),
{'$lgt_cpu_time'(Seconds2)},
Looptime is Seconds2 - Seconds1,
{'$lgt_cpu_time'(Seconds3)},
do_benchmark(Id, N),
{'$lgt_cpu_time'(Seconds4)},
Goaltime is Seconds4 - Seconds3,
Average is (Goaltime - Looptime)/N,
Speed is 1.0/Average.
report(Id, Goal, N, Looptime, Goaltime, Average, Speed) :-
write(Id), write(': '),
writeq(Goal), nl,
write('Number of repetitions: '), write(N), nl,
write('Loop time: '), write(Looptime), nl,
write('Goal time: '), write(Goaltime), nl,
write('Average time per call: '), write(Average), nl,
write('Number of calls per second: '), write(Speed), nl,
nl.
% some benchmark tests for static code:
benchmark(s1, my_length(List, _)) :-
{generate_list(20, List)}.
benchmark(s2, object::length(List, _)) :-
{generate_list(20, List)}.
% some benchmark tests for category predicate calls:
benchmark(c1, leaf::ctg_direct).
benchmark(c2, leaf::ctg_self).
% some benchmark tests for dynamic code:
benchmark(d1, (create_object(xpto, [], [], []), abolish_object(xpto))).
benchmark(d2, plain_dyndb(_)).
benchmark(d3, database::this_dyndb(_)).
benchmark(d4, database::self_dyndb(_)).
benchmark(d5, database::obj_dyndb(_)).
% repeat a goal N times without using call/1 and using a failure-driven loop to
% avoid the interference of Prolog compiler memory management mechanism (such as
% garbage collection) on the results
do_benchmark(empty_loop, N) :-
{my_repeat(N)},
fail.
do_benchmark(empty_loop, _).
do_benchmark(s1, N) :-
{generate_list(20, List)},
{my_repeat(N)},
{my_length(List, _)},
fail.
do_benchmark(s1, _).
do_benchmark(s2, N) :-
{generate_list(20, List)},
{my_repeat(N)},
object::length(List, _),
fail.
do_benchmark(s2, _).
do_benchmark(c1, N) :-
{my_repeat(N)},
leaf::ctg_direct,
fail.
do_benchmark(c1, _).
do_benchmark(c2, N) :-
{my_repeat(N)},
leaf::ctg_self,
fail.
do_benchmark(c2, _).
do_benchmark(d1, N) :-
{my_repeat(N)},
create_object(xpto, [], [], []),
abolish_object(xpto),
fail.
do_benchmark(d1, _).
do_benchmark(d2, N) :-
{my_repeat(N)},
{plain_dyndb(N)},
fail.
do_benchmark(d2, _).
do_benchmark(d3, N) :-
{my_repeat(N)},
database::this_dyndb(N),
fail.
do_benchmark(d3, _).
do_benchmark(d4, N) :-
{my_repeat(N)},
database::self_dyndb(N),
fail.
do_benchmark(d4, _).
do_benchmark(d5, N) :-
{my_repeat(N)},
database::obj_dyndb(N),
fail.
do_benchmark(d5, _).
:- end_object.

View File

@@ -0,0 +1,14 @@
:- category(category).
:- info([
version is 1.0,
author is 'Paulo Moura',
date is 2007/06/10,
comment is 'Defines a simple predicate for comparing performance of calls from within an object to imported category predicates.']).
:- public(ctg_pred/0).
ctg_pred.
:- end_category.

View File

@@ -1,38 +1,47 @@
:- object(database).
:- public(db_test_this/0, db_test_self/0, db_test_obj/0).
:- info([
version is 2.0,
author is 'Paulo Moura',
date is 2007/04/17,
comment is 'Dynamic database benchmark utility predicates.']).
:- private(pred_this/0, pred_self/0, pred_obj/0).
:- dynamic(pred_this/0, pred_self/0, pred_obj/0).
:- public(this_dyndb/1).
:- mode(this_dyndb(+nonvar), one).
:- info(this_dyndb/1, [
comment is 'Asserts and retracts a predicate in "this".',
argnames is ['Term']]).
db_test_this :-
{repeat(100)},
assertz(pred_this),
fail.
db_test_this :-
retract(pred_this),
fail.
db_test_this.
:- public(self_dyndb/1).
:- mode(self_dyndb(+nonvar), one).
:- info(self_dyndb/1, [
comment is 'Asserts and retracts a predicate using ::/1.',
argnames is ['Term']]).
db_test_self :-
{repeat(100)},
::assertz(pred_self),
fail.
db_test_self :-
::retract(pred_self),
fail.
db_test_self.
:- public(obj_dyndb/1).
:- mode(obj_dyndb(+nonvar), one).
:- info(obj_dyndb/1, [
comment is 'Asserts and retracts a predicate using ::/2.',
argnames is ['Term']]).
:- private([pred_this/1, pred_self/1, pred_obj/1]).
:- dynamic([pred_this/1, pred_self/1, pred_obj/1]).
db_test_obj :-
% direct calls to assertz/1 and retract/1:
this_dyndb(N) :-
assertz(pred_this(N)),
retract(pred_this(N)).
% calls to assertz/1 and retract/1 using ::/1:
self_dyndb(N) :-
::assertz(pred_self(N)),
::retract(pred_self(N)).
% calls to assertz/1 and retract/1 using ::/2:
obj_dyndb(N) :-
this(This),
{repeat(100)},
This::assertz(pred_obj),
fail.
db_test_obj :-
this(This),
This::retract(pred_obj),
fail.
db_test_obj.
This::assertz(pred_obj(N)),
This::retract(pred_obj(N)).
:- end_object.

View File

@@ -2,5 +2,7 @@
% uncomment the next line if your Prolog compiler supports modules
%:- ensure_loaded(module).
:- initialization(
logtalk_load([benchmark, plain, object, database])).
:- initialization((
logtalk_load([category], [events(off), reload(skip)]),
logtalk_load([objects, database], [events(off), reload(skip)]),
logtalk_load([plain, benchmarks], [events(off)]))).

View File

@@ -0,0 +1,6 @@
% uncomment the next line if your Prolog compiler supports modules
%:- ensure_loaded(module).
:- initialization(
logtalk_load([category, objects, database, plain, benchmarks], [events(on)])).

View File

@@ -0,0 +1,6 @@
% uncomment the next line if your Prolog compiler supports modules
%:- ensure_loaded(module).
:- initialization(
logtalk_load([category, objects, database, plain, benchmarks], [events(off)])).

View File

@@ -0,0 +1,8 @@
% uncomment the next line if your Prolog compiler supports modules
%:- ensure_loaded(module).
:- initialization((
logtalk_load([category], [events(off), reload(skip)]),
logtalk_load([objects, database], [events(off), reload(skip)]),
logtalk_load([plain, benchmarks], [events(off)]))).

View File

@@ -6,11 +6,11 @@
mod_length(List, Length) :-
integer(Length) ->
( integer(Length) ->
Length >= 0,
mod_make_list(Length, List)
;
mod_length(List, 0, Length).
; mod_length(List, 0, Length)
).
mod_make_list(0, []):-

View File

@@ -0,0 +1,60 @@
:- object(object,
imports(category)).
:- info([
version is 3.0,
author is 'Paulo Moura',
date is 2007/06/11,
comment is 'Example object for benchmarking library predicate calls and imported category predicate calls.']).
:- public(length/2).
length(List, Length) :-
length(List, 0, Length).
length([], Length, Length).
length([_| Tail], Acc, Length) :-
Acc2 is Acc + 1,
length(Tail, Acc2, Length).
:- public(ctg_self/0).
% call an imported category predicate by sending a message to self;
% performance will depend on the distance between "self" and "this"
% (always uses dynamic binding)
ctg_self :-
::ctg_pred.
:- public(ctg_direct/0).
% call an imported category predicate directly by using the :/1 control construct;
% (static binding may be used, depending on how the category is compiled)
ctg_direct :-
:ctg_pred.
:- end_object.
:- object(descendant,
extends(object)).
:- info([
version is 1.0,
author is 'Paulo Moura',
date is 2007/04/17,
comment is 'Example object used for simulating a small hierarchy.']).
:- end_object.
:- object(leaf,
extends(descendant)).
:- info([
version is 1.0,
author is 'Paulo Moura',
date is 2007/04/17,
comment is 'Example object used for simulating a small hierarchy.']).
:- end_object.

View File

@@ -1,36 +1,42 @@
my_length(List, Length) :-
integer(Length) ->
Length >= 0,
my_make_list(Length, List)
;
my_length(List, 0, Length).
my_make_list(0, []):-
!.
my_make_list(N, [_| Tail]):-
M is N-1,
my_make_list(M, Tail).
my_length(List, 0, Length).
my_length([], Length, Length).
my_length([_| Tail], Acc, Length) :-
Acc2 is Acc + 1,
my_length(Tail, Acc2, Length).
:- dynamic(pred_plain/0).
:- dynamic(pred_plain/1).
db_test_plain :-
repeat(100),
assertz(pred_plain),
fail.
plain_dyndb(N) :-
assertz(pred_plain(N)),
retract(pred_plain(N)).
db_test_plain :-
retract(pred_plain),
fail.
db_test_plain.
my_between(Lower, _, Lower).
my_between(Lower, Upper, Integer) :-
Lower < Upper,
Next is Lower + 1,
my_between(Next, Upper, Integer).
my_repeat(_).
my_repeat(N) :-
N > 1,
N2 is N - 1,
my_repeat(N2).
% generate a list containing the first N non-negative integers
generate_list(N, List) :-
generate_list(0, N, List).
generate_list(N, N, []) :-
!.
generate_list(M, N, [M| Ms]) :-
M < N,
M2 is M + 1,
generate_list(M2, N, Ms).