From: john.watto (John D. Watton)

Subject: Franz ACL 4.3.2 for Windows compared to ACL 3.0.1

Date: 1997-6-7 20:49

I recently got to try out a beta copy of Franz ACL 4.3.2 for
Windows. It is a port of their UNIX optimizing compiler to
Windows. Not to be confused with their port of 4.3 to Linux. Anyway,
based on my two benchmarks it has much performance gain over Franz ACL
3.0.1. Which makes me wonder why Franz doesn't promote it. It comes
with the same development environment as the Unix product using GNU
emacs 19.34 as the editor. You won't find this product memtioned
anywhere on their web site (except the UNIX and Linux versions). I
don't know if Common-Graphics or Clim is available or if there is any
GUI builder available for or included in our beta copy.

Machine: Pentium 90 Mhz, 40 M memory
OS: Windows NT 3.51

Pnpoly Benchmark       sec
----------------       ---
VC++ 4.2 (cl -Ox)     15.4
Franz ACL 4.3.2       22.8
Franz ACL 3.0.1      525.6
Perl5.003           1196.0

Rhyme Benchmark     read string sort write total
---------------     ----  rev's ---- ----- -----
                         ------
Franz ACL 4.3.2     1.84  1.44  2.22  0.74  6.24
Perl5.003           2.00 16.00  2.00  2.00 22.00
Franz ACL 3.0.1    30.10  1.60  5.35 19.60 56.65

Notes: The original C version of pnpoly came from the Usenet
comp.graphics.algorithms FAQ. It is a function to determine if a 2d
point is inside a closed polygon using the ray crossing algorithm. The
rhyme benchmark is based on the code on page 224 of "ANSI Common Lisp"
by Paul Graham. It is a function that reads a file of words one per
line and composes a rhyming dictionary with them. For this test I
copied the file /usr/dict/words from a UNIX machine (approx 25000
words). Unfortunately, I don't have a C version of this benchmark. It
seemed like a lot of work compared to how easily it can be done in
lisp or Perl.


LISP-RHYME-LISP-RHYME-LISP-RHYME-LISP-RHYME-LISP-RHYME-LISP-RHYME-LISP

(defun rhyme (from to &aux dict)
 ;; for from file use /usr/dict/words from a UNIX machine
  (declare (optimize (speed 3) (safety 0)))
     (with-open-file (in from :direction :input)
       (setq dict (loop for w = (read-line in nil nil)
                    until (not w) collect w)))
     (setq dict (mapc #'nreverse dict))
     (setq dict (sort dict #'string<))
     (setq dict (mapc #'nreverse dict))
     (with-open-file (out to :direction :output :if-exists :supersede)
       (dolist (x dict) (write-line x out))))

LISP-PNPOLY-LISP-PNPOLY-LISP-PNPOLY-LISP-PNPOLY-LISP-PNPOLY-LISP-PNPOLY

(defun pnpoly (npol xp yp x y)
  (declare (optimize (speed 3) (safety 0))
	   (fixnum npol)
	   (double-float x y)
	   (type (simple-array double-float (*)) xp yp))
  (let* ((c nil)
	 (j (1- npol)))
    (declare (fixnum j))
    (dotimes (i npol c)
      (declare (fixnum i))
      (if (and (or (and (<= (aref yp i) y) (< y (aref yp j)))
		   (and (<= (aref yp j) y) (< y (aref yp i))))
	       (< x (+ (aref xp i) (/ (* (- (aref xp j) (aref xp i)) (- y (aref yp i)))
				      (- (aref yp j) (aref yp i))))))
	  (setq c (not c)))
      (setq j i))))

(defun pnpolytest ()
  (declare (optimize (speed 3) (safety 0)))
  (let ((npol 20)
	(count 0)
	(xp (make-array 20 :element-type 'double-float
			:initial-contents '(0.0d0 1.0d0 1.0d0 0.0d0 0.0d0 1.0d0 -0.5d0 -1.0d0
					    -1.0d0 -2.0d0 -2.5d0 -2.0d0 -1.5d0 -0.5d0 1.0d0
					    1.0d0 0.0d0 -0.5d0 -1.0d0 -.5d0)))
	(yp (make-array 20 :element-type 'double-float
			:initial-contents '(0.0d0 0.0d0 1.0d0 1.0d0 2.0d0 3.0d0 2.0d0 3.0d0
					    0.0d0 -0.5d0 -1.0d0 -1.5d0 -2.0d0 -2.0d0 -1.5d0
					    -1.0d0 -0.5d0 -1.0d0 -1.0d0 -0.5d0))))
    (declare (fixnum npol count)
	     (type (simple-array double-float (20)) xp yp))
    (dotimes (i 100000)
      (if (pnpoly npol xp yp 0.5d0 0.5d0) (incf count))
      (if (pnpoly npol xp yp 0.5d0 1.5d0) (incf count))
      (if (pnpoly npol xp yp -0.5d0 1.5d0) (incf count))
      (if (pnpoly npol xp yp 0.75d0 2.25d0) (incf count))
      (if (pnpoly npol xp yp 0.0d0 2.01d0) (incf count))
      (if (pnpoly npol xp yp -0.5d0 2.5d0) (incf count))
      (if (pnpoly npol xp yp -1.0d0 -0.5d0) (incf count))
      (if (pnpoly npol xp yp -1.5d0 0.5d0) (incf count))
      (if (pnpoly npol xp yp -2.25d0 -1.0d0) (incf count))
      (if (pnpoly npol xp yp 0.5d0 -0.25d0) (incf count))
      (if (pnpoly npol xp yp 0.5d0 -1.25d0) (incf count))
      (if (pnpoly npol xp yp -0.5d0 -2.5d0) (incf count)))
    (princ "Count ") (princ count)
    count))

PERL-RHYME-PERL-RHYME-PERL-RHYME-PERL-RHYME-PERL-RHYME-PERL-RHYME-PERL

$in = "words.txt";
open(INFILE, $in);
while (<INFILE>) {
    chop;
    push @words, $_;
}
@words = map {pack "C*", (reverse (unpack "C*", $_))} @words;
@words = sort @words;
@words = map {pack "C*", (reverse (unpack "C*", $_))} @words;
$out = "rhyme.txt";
open(OUTFILE, ">$out");
map {print (OUTFILE $_, "\n")} @words;

PERL-PNPOLY-PERL-PNPOLY-PERL-PNPOLY-PERL-PNPOLY-PERL-PNPOLY-PERL

sub pnpoly {
    my($npol, $xxp, $yyp, $x, $y) = @_;
    my($j, $c, $i) = ($npol - 1, 0, 0);
    for ($i = 0; $i < $npol; $i++) {
	if (((($$yyp[$i] <= $y) && ($y < $$yyp[$j])) ||
	     (($$yyp[$j] <= $y) && ($y < $$yyp[$i]))) &&
	    ($x < (($$xxp[$j] - $$xxp[$i]) * 
		   ($y - $$yyp[$i]) /
		   ($$yyp[$j] - $$yyp[$i]) + $$xxp[$i]))) {
	    $c = !$c;}
	$j = $i;
    }
    $c;
}

sub pnpolytest {
    local($npol, $count, @xp, @yp);
    $npol ;
    $count=0;
    @xp = (0.0,1.0,1.0,0.0,0.0,1.0,-.5,-1.0,-1.0,-2.0,
	   -2.5,-2.0,-1.5,-.5,1.0,1.0,0.0,-.5,-1.0,-.5);
    @yp = (0.0,0.0,1.0,1.0,2.0,3.0,2.0,3.0,0.0,-.5,
	   -1.0,-1.5,-2.0,-2.0,-1.5,-1.0,-.5,-1.0,-1.0,-.5);
    for(1..100000) { 
	if <yp,0.5,0.5)) at (pnpoly($npol,\@xp,\> {$count++};
	if <yp,0.5,1.5)) at (pnpoly($npol,\@xp,\> {$count++};
	if <yp,-0.5,1.5)) at (pnpoly($npol,\@xp,\> {$count++};
	if <yp,0.75,2.25)) at (pnpoly($npol,\@xp,\> {$count++};
	if <yp,0.0,2.01)) at (pnpoly($npol,\@xp,\> {$count++};
	if <yp,-0.5,2.5)) at (pnpoly($npol,\@xp,\> {$count++};
	if <yp,-1.0,-0.5)) at (pnpoly($npol,\@xp,\> {$count++};
	if <yp,-1.5,0.5)) at (pnpoly($npol,\@xp,\> {$count++};
	if <yp,-2.25,-1.0)) at (pnpoly($npol,\@xp,\> {$count++};
	if <yp,0.5,-0.25)) at (pnpoly($npol,\@xp,\> {$count++};
	if <yp,0.5,-1.25)) at (pnpoly($npol,\@xp,\> {$count++};
	if <yp,-0.5,-2.5)) at (pnpoly($npol,\@xp,\> {$count++};
    }
    print "\n count ", $count, "\n";
}

C-PNPOLY-C-PNPOLY-C-PNPOLY-C-PNPOLY-C-PNPOLY-C-PNPOLY-C-PNPOLY-C

int pnpoly(int npol, double *xp, double *yp, double x, double y)
{
  int i, j, c = 0;
  for (i = 0, j = npol-1; i < npol; j = i++) {
    if ((((yp[i]<=y) && (y<yp[j])) ||
	 ((yp[j]<=y) && (y<yp[i]))) &&
	(x < (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i]))
      c = !c;
  }
  return c;
}

main() {
  int npol , count=0;
  double xp[20]= {0.0,1.0,1.0,0.0,0.0,1.0,-0.5,-1.0,-1.0,-2.0,
		  -2.5,-2.0,-1.5,-.5,1.0,1.0,0.0,-0.5,-1.0,-.5};
  double yp[20]= {0.0,0.0,1.0,1.0,2.0,3.0,2.0,3.0,0.0,-.5,
		  -1.0,-1.5,-2.0,-2.0,-1.5,-1.0,-.5,-1.0,-1.0,-.5};
  int i=0;
  for(i=0;i<100000;i++) {
    if (pnpoly(npol,xp,yp,0.5,0.5)) count++;
    if (pnpoly(npol,xp,yp,0.5,1.5)) count++;
    if (pnpoly(npol,xp,yp,-0.5,1.5)) count++;
    if (pnpoly(npol,xp,yp,0.75,2.25)) count++;
    if (pnpoly(npol,xp,yp,0.0,2.01)) count++;
    if (pnpoly(npol,xp,yp,-0.5,2.5)) count++;
    if (pnpoly(npol,xp,yp,-1.0,-0.5)) count++;
    if (pnpoly(npol,xp,yp,-1.5,0.5)) count++;
    if (pnpoly(npol,xp,yp,-2.25,-1.0)) count++;
    if (pnpoly(npol,xp,yp,0.5,-0.25)) count++;
    if (pnpoly(npol,xp,yp,0.5,-1.25)) count++;
    if (pnpoly(npol,xp,yp,-0.5,-2.5)) count++;
  }
  printf("count %d \n", count);
  return(0);
}

--
John D. Watton
Alcoa