1% ----------------------------------------------------------------------
2% BEGIN LICENSE BLOCK
3% Version: CMPL 1.1
4%
5% The contents of this file are subject to the Cisco-style Mozilla Public
6% License Version 1.1 (the "License"); you may not use this file except
7% in compliance with the License.  You may obtain a copy of the License
8% at www.eclipse-clp.org/license.
9%
10% Software distributed under the License is distributed on an "AS IS"
11% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
12% the License for the specific language governing rights and limitations
13% under the License.
14%
15% The Original Code is  The ECLiPSe Constraint Logic Programming System.
16% The Initial Developer of the Original Code is  Cisco Systems, Inc.
17% Portions created by the Initial Developer are
18% Copyright (C) 1991-2006 Cisco Systems, Inc.  All Rights Reserved.
19%
20% Contributor(s): ECRC GmbH
21% Contributor(s): IC-Parc, Imperal College London
22%
23% END LICENSE BLOCK
24%
25% System:	ECLiPSe Constraint Logic Programming System
26% Version:	$Id: lips.pl,v 1.3 2009/07/16 09:11:24 jschimpf Exp $
27% ----------------------------------------------------------------------
28
29%
30% SEPIA PROLOG LIBRARY MODULE
31%
32% IDENTIFICATION:	lips.pl
33%
34% AUTHOR:		Joachim Schimpf
35%
36% CONTENTS:		lips/0,1,2
37%
38% DESCRIPTION:		Measure the system's speed using naive reverse
39%
40
41:- module(lips).
42
43:- comment(categories, ["Development Tools"]).
44:- comment(summary, "Measure the system's speed using the naive reverse benchmark").
45:- comment(author, "Joachim Schimpf, ECRC Munich").
46:- comment(copyright, "Cisco Systems, Inc").
47:- comment(date, "$Date: 2009/07/16 09:11:24 $").
48:- comment(desc, html("
49    Measure the system's speed in logical inferences per second, using
50    the infamous naive reverse program. This test does not say very much
51    about the quality of a system. All it gives is an indication about
52    the speed of list processing.
53    <P>
54    The executed program is:
55    <PRE>
56    nreverse([], []).
57    nreverse([X|L0],L) :-
58	    nreverse(L0, L1),
59	    concatenate(L1, [X], L).
60
61    concatenate([], L, L).
62    concatenate([X|L1], L2, [X|L3]) :-
63	    concatenate(L1, L2, L3).
64    </PRE>
65    and the standard benchmark is to call nreverse/2 with a 30-element
66    list as the first and a variable as the second argument.  This
67    instance is assumed to have 496 logical inferences.
68    ")).
69:- comment(lips/0, [template:"lips",
70    summary:"Run the benchmark a reasonable number of times and print the average speed"
71    ]).
72:- comment(lips/1, [template:"lips(+Count)",
73    summary:"Run the benchmark Count times and print the average speed"
74    ]).
75:- comment(lips/2, [template:"lips(+Count,+Length)",
76    summary:"Run the benchmark Count times with lists of length Length"
77    ]).
78
79:- export lips/0, lips/1, lips/2.
80
81:- pragma(nodebug).
82?- set_flag(gc, off).
83
84lips :-
85	lips(10000, 30).
86
87lips(Count) :-
88	lips(Count, 30).
89
90lips(Count, Length) :-
91	conslist(Length, List),
92
93	cputime(T4),
94	compens_loop(Count, List),
95	cputime(T5),
96	Empty is T5-T4,
97
98	cputime(T0),
99	call_loop(Count, List),
100	cputime(T1),
101	T is T1-T0-Empty,
102
103	printf("%d iterations of nrev(%d)\n", [Count,Length]),
104
105	LI is Length*(Length+3)/2 + 1,
106	LIPS is LI * Count / T / 1000,
107	printf("%d * %.1f inferences / %.3f seconds / 1000 = %.1f KLIPS\n",
108		[Count,LI,T,LIPS]).
109
110
111compens_loop(N, List) :-
112	setval(count, N),
113	repeat,
114	dummy(List,_),
115	decval(count),
116	getval(count, 0),
117	!.
118
119call_loop(N, List) :-
120	setval(count, N),
121	repeat,
122	nreverse(List,_),
123	decval(count),
124	getval(count, 0),
125	!.
126
127conslist(0, []) :- !.
128conslist(N, [N|L]) :-
129	N1 is N-1,
130	conslist(N1, L).
131
132dummy(_,_).
133
134% This is the benchmark:
135
136nreverse([], []).
137nreverse([X|L0],L) :-
138	nreverse(L0, L1),
139	concatenate(L1, [X], L).
140
141concatenate([], L, L).
142concatenate([X|L1], L2, [X|L3]) :-
143	concatenate(L1, L2, L3).
144
145:- writeln("Call lips/0 to run the standard naive reverse benchmark.").
146