⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bench_pl.pro

📁 经典的基于Context-Free_Grammer 的语法分析器。
💻 PRO
字号:
/* BENCH.PL : The classic Prolog benchmark

        Supplied by Quintus Computer Systems, Inc.
        April 30th 1984
*/

/* ======================================================================
   This benchmark gives the raw speed of a Prolog system.

   The measure of logical inferences per second (Lips) used here is taken to
   be procedure calls per second over an example with not very complex
   procedure calls. The example used is that of "naive reversing" a list,
   which is an expensive, and therefore stupid, way of reversing a list.  It
   does, however, produce a lot of procedure calls. (In theoretical terms,
   this algorithm is O(n^2) on the length of the list).

   The use of a single simple benchmark like this cannot, of course, be
   taken to signify a great deal. However, experience has shown that this
   benchmark does provide a very good measure of basic Prolog speed and
   produces figures which match more complex benchmarks. The reason for
   this is that the basic operations performed here: procedure calls with a
   certain amount of data structure access and construction; are absolutely
   fundamental to Prolog execution. If these are done right, then more
   complex benchmarks tend to scale accordingly. This particular benchmark
   has thus been used as a good rule of thumb by Prolog implementors for
   over a decade and forms a part of the unwritten Prolog folklore. So -
   use this benchmark, with this in mind, as a quick, but extremely useful,
   test of Prolog performance.

   In a complete evaluation of a Prolog system you should also be taking
   account speeds of asserting and compiling, tail recursion, memory
   utilisation, compactness of programs, storage management and garbage
   collection, debugging and editing facilities, program checking and help
   facilities, system provided predicates, interfaces to external
   capabilities, documentation and support, amongst other factors.

   ====================================================================== */


/* ----------------------------------------------------------------------
        get_cpu_time(T) -- T is the current cpu time.

        ** This bit will probably require changes to work on your Prolog
           system, since different systems provide this facility in
           different ways. See your Prolog manual for details.
        ** Also check the code for calculate_lips/4 below.
   ---------------------------------------------------------------------- */


get_cpu_time(T) :- statistics(runtime,[T,_]). /* Quintus Prolog version */

/*  get_cpu_time(T) :- T is cputime.     C-Prolog version       */


/* ----------------------------------------------------------------------
        nrev(L1,L2)      -- L2 is the list L1 reversed.
        append(L1,L2,L3) -- L1 appended to L2 is L3.
        data(L)          -- L is a thirty element list.

        This is the program executed by the benchmark.
        It is called "naive reverse" because it is a very expensive way
        of reversing a list. Its advantage, for our purposes, is that
        it generates a lot of procedure calls. To reverse a thirty element
        list requires 496 Prolog procedure calls.
   ---------------------------------------------------------------------- */

nrev([],[]).
nrev([X|Rest],Ans) :- nrev(Rest,L), append(L,[X],Ans).

append([],L,L).
append([X|L1],L2,[X|L3]) :- append(L1,L2,L3).


data([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,30]).


/* ----------------------------------------------------------------------
        lots -- Run benchmark with a variety of iteration counts.

        Call this to run the benchmark with increasing numbers
        of iterations. The figures produced should be about the same -
        except that there may be inaccuracies at low iteration numbers
        if the time these examples take to execute on your machine are
        too small to be very precise (because of the accuracy the
        operating system itself is capable of providing).
        If the time taken for these examples is too long or short then
        you should adjust the eg_count(_) facts.
   ---------------------------------------------------------------------- */

lots :-
        eg_count(Count),
        bench(Count),
        fail.
lots.

eg_count(10).
eg_count(20).
eg_count(50).
eg_count(100).
eg_count(200).
eg_count(500).
eg_count(1000).
eg_count(2000).
eg_count(5000).
eg_count(10000).


/* ----------------------------------------------------------------------
        bench(Count) -- Run the benchmark for Count iterations.

        bench provides a test harness for running the naive reverse
        benchmark. It is important to factor out the overhead of setting
        the test up and using repeat(_) to iterate the right number of
        times. This is done by running some dummy code as well to see how
        much time the extra operations take.
   ---------------------------------------------------------------------- */

bench(Count) :-
        get_cpu_time(T0),
        dodummy(Count),
        get_cpu_time(T1),
        dobench(Count),
        get_cpu_time(T2),
        report(Count,T0,T1,T2).


/* ----------------------------------------------------------------------
        dobench(Count) -- nrev a 30 element list Count times.
        dodummy(Count) -- Perform the overhead operations Count times.
        repeat(Count)  -- Predicate which succeeds Count times

        This is the supporting code, which is reasonably clear.
   ---------------------------------------------------------------------- */

dobench(Count) :-
        data(List),
        repeat(Count),
        nrev(List,_),
        fail.
dobench(_).


dodummy(Count) :-
        data(List),
        repeat(Count),
        dummy(List,_),
        fail.
dodummy(_).

dummy(_,_).

repeat(_N).
repeat(N) :- N >1, N1 is N-1, repeat(N1).


/* ----------------------------------------------------------------------
        report(Count,T0,T1,T2) -- Report the results of the benchmark.
        calculate_lips(Count,Time,Lips,Units) --
                Doing Count interations in Time implies Lips lips assuming
                that time is given in Units.

        This calculates the logical inferences per second (lips) figure.
        Remember that it takes 496 procedure calls to naive reverse a
        thirty element list once. Lips, under this benchmark, thus means
        "Prolog procedure calls per second, where the procedure calls
        are not too complex (i.e. those for nrev and append)".

        ** This version of the code assumes that the times (T0.. etc)
           are integers giving the time in milliseconds. This is true for
           Quintus Prolog.  Your Prolog system may use some other
           representation.  If so, you will need to adjust the Lips
           calculation.  There is a C-Prolog version below for the case
           where times are floating point numbers giving the time in
           seconds.
   ---------------------------------------------------------------------- */

report(Count,T0,T1,T2) :-
        Time1 is T1-T0,
        Time2 is T2-T1,
        Time  is Time2-Time1,           /* Time spent on nreving lists */
        calculate_lips(Count,Time,Lips,Units),
        nl,
        write(Lips), write(' lips for '), write(Count),
        write(' iterations taking '), write(Time),
        write(' '), write(Units), write(' ('),
        write(Time2-Time1), write(')'),
        nl.



calculate_lips(_Count,Time,Lips,'msecs') :-     /* Time can be 0 for small */
        Time is 0, !, Lips is 0.                /* values of Count!        */
calculate_lips(Count,Time,Lips,'msecs') :-
        Lips  is (496*float(Count)*1000)/Time.

/* --- C-Prolog version

calculate_lips(Count,Time,Lips,'secs') :- Lips  is (496*Count)/Time.

   --- */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -