[net.lang.prolog] LIPS

micha@ecrcvax.UUCP (06/13/86)

Some people seem to have a wrong idea about the speed of the programs
compiled by the up-to-date Prolog compilers. The following might help
to determine the performance of a good Prolog compiler 
on a given machine (measuring naive reverse). The C program simulates
the output of the compiler using many optimizations (not all) and
with no restrictions on Prolog syntax. 
If your system is better, congratulations; if it is significantly
slower, you can certainly find a system for your machine which has
a similar performance.

Micha


----cut here----

/*
 * Measure possible LIPS on the naive reverse example. LENGTH is
 * the maximal length of the list to reverse which also determines
 * the stack size (b).
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/times.h>
#define	HZ 60.0			/* might need to change this */

#define LENGTH	300
#define a	(LENGTH+2)*(LENGTH+2)
#define b	a + 6*LENGTH
#define c	((unsigned) 0)
#define d	((unsigned) 0x10000000)
#define e	((unsigned) 0x20000000)
#define f(X)	((unsigned) (X & 0xf0000000))
#define g(X)	((unsigned) (X & 0xfffffff))
#define h(X)	((unsigned) (X | 0x30000000))
#define i(X)	((unsigned) (X | d))
#define j(k, l)	{l = k; while (f(l) == c) {l = m[l];}}
#define n(k, o, l) {l = k; if ((o = f(l)) == c)	{l = m[l]; o = f(l);} l = g(l);}
#define p(q)	if (q < t || (q < u && q > a)) r[v++] = q;
#define s	if (w > b) {fprintf(stderr, "something went wrong\n"); exit(2);}
#define z	if (y > a) {fprintf(stderr, "something went wrong\n"); exit(2);}

unsigned m[b], r[1];
main()
{
	register unsigned aa, y, ab, ac, ae, x, ag, t, af, u, w, v, ad;
	int ah, length, t0;
	struct tms Time;
	float Lips;

	y = 1, t = 0, u = af = 0, w = a;
	printf("List length: ");
	scanf("%d", &length);
	if (length > LENGTH) {
		fprintf(stderr, "\nSorry, this is too much\n");
		exit(2);
	}
	for (ah = 1; ah < length; ah++) {
		m[y++] = h(ah), m[y] = i(y+1), y++;
	}
	m[y++] = h(ah), m[y++] = e;
	m[0] = 0, x = i(1), ag = 0;
	times(&Time);
	t0 = Time.tms_utime;
	goto aj;
ai:	times(&Time);
	t0 = Time.tms_utime - t0;
	if (t0 == 0) {
		fprintf(stderr, "The time is too short to measure, sorry\n");
		exit(1);
	}
	Lips = ((length * (length + 3))/2 + 1) / (t0/HZ);
	printf("\nLips = %.1f\n", Lips);
	exit(0);
aj:	n(x, ab, aa);
	if (ab != d) {
		n(ag, ab, aa);
		p(aa);
		m[aa] = e;
	}
	else {
		m[w] =  af, af = w++, m[w++] = ad, w += 3;
		s;
		m[af+4] = aa++, x = aa++, m[af+3] = ag; 
		ab = af+2, m[ab] = ag = ab;
		goto aj;
	}
ak:	ag = i(y);
	j(m[af+4], aa);
	m[y++] = aa, m[y++] = e;
	z;
	if (u < af) {
		j(m[af+2], aa);
		if (f(aa) == c) {} else x = aa;
	}
	ac = m[af+3], ad = m[af+1], af = m[af];
	if (af > u) w = af; else w = u;
	for(;;) {
		n(x, ab, aa);
		if (ab != d) {
			n(ac, ab, aa);
			p(aa);
			m[aa] = ag;
			if (af == 0) goto ai; else goto ak;
		}
		ae = m[aa++], x = m[aa++];
		n(ac, ab, aa);
		p(aa);
		m[aa] = i(y), m[y++] = ae, m[y] = y, ac = y++;
		z;
	}
}