From: John Watton
Subject: Update: Comparing C, Lisp, Tcl, Perl, Python, Java, & Scheme (Guile) Using a Floating Point Numerical Test - Point Inside Polygon
Date:
Message-ID: <uiv0ox4ag.fsf@alcoa.com>
Comparing C, Lisp, Tcl, Perl, Python, Java, & Scheme (Guile) Using a
Floating Point Numerical Test - Point Inside Polygon
This is an update on a small study I did to compare various computing
languages, especially those interpreted types that seem to get so much
interest for one reason or another. I wanted to know how they compared
to each other syntax wise and performance wise and also how they
compare to languages that have a native compiler available. Others
more experienced in a particular language have offered improvements
that are incorporated. The only change in order was movement of Perl
ahead of Tcl and Guile. Please don't flame me if your favorite didn't
fair well - this test very much favors speed of floating point
numerical calculation. Please don't be the next person to tell me
that you can embed the C version into Perl, Tcl, etc. I still believe
a direct comparison is helpful. Also this test does not consider the
various ...to-C compilers available for Tcl, Perl, and Scheme.
The test is actually some very useful code in computer graphics. It is
a function to determine if a 2D point is inside a closed 2D
polygon. The polygon need not be convex. The original C version came
from the comp.graphics.algorithms FAQ. The function is called on 12
different points half in and half out (alternating) for 100000
iterations summing up how many points are inside - which comes to
12*1/2*100000 or 600000 if the code is correct - just in case you want
to write a version for a language I didn't get to. Thanks to everyone
who offered suggestions.
More happy computing!
MACHINE-TYPE: SPARCstation10 100MHz 128Mb RAM
SOFTWARE-VERSION: SunOS 5.4 Generic_101945-27 sun4m
native compiler time (sec) lang html
--------------- ---------- ---- ----
gcc -O3 (2.7.2) 6.0 C www.gnu.ai.mit.edu
gcc -O2 (2.7.2) 6.1 C
Franz Allegro Lisp 4.3 8.4 Common Lisp www.franz.com
cc -O (SC3.0.1) 8.5 C
cc (SC3.0.1) 15.4 C
interpreter
-----------
Sun's Java 1.0.2 163.0 Java www.javasoft.com
CINT (C/C++ interpr.) 530.0 C hpsalo.cern.ch/root/Cint
Python1.4 1280.0 Python www.python.org
Perl5.003 1710.0 Perl www.perl.com
Guile1.0 2060.0 Scheme www.gnu.ai.mit.edu
Tcl8.0a2 2240.0 Tcl sunscript.sun.com
Tcl7.4 24600.0 Tcl
CHANGES
-------
1. Perl version improved significantly.
2. Python version fixed (I left out an j=i statement) and improved
mostly stylistically.
3. Minor change to Java version to make pnpoly method static.
4. Tcl version improved.
COMMENTS
--------
1. Unsuprisingly, native compiled code is much faster than interpreted.
2. Tcl 8.0 is much improved over Tcl 7.4.
3. Typed interpreted (Java & CINT) outperforms untyped interpreted.
4. Going into Tcl, Perl, Java, and Python almost cold - Python was
fastest to pick up on and debug; Tcl the slowest (but I used 7.4).
5. Java has no functions except methods on objects but with the static
keyword on methods at least you don't have to instantiate a dummy
class. Still irritating.
6. CINT 5.13 has a bug: replace c = !c; with c ^= 1; to get around.
C-CINT-C-CINT-C-CINT-C-CINT-C-CINT-C-CINT-C-CINT-C-CINT-C-CINT-C-CINT-C-CINT
/*The code below is from Wm. Randolph Franklin <···@ecse.rpi.edu>
with some minor modifications for speed.
comp.graphics.algorithms FAQ
References:
[Gems IV] pp. 24-46
[O'Rourke] pp. 233-238
[Glassner:RayTracing] */
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=20, count=0;
double xp[20]= {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};
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,-.5,1.5)) count++;
if (pnpoly(npol,xp,yp,0.75,2.25)) count++;
if (pnpoly(npol,xp,yp,0,2.01)) count++;
if (pnpoly(npol,xp,yp,-.5,2.5)) count++;
if (pnpoly(npol,xp,yp,-1.0,-.5)) count++;
if (pnpoly(npol,xp,yp,-1.5,.5)) count++;
if (pnpoly(npol,xp,yp,-2.25,-1.0)) count++;
if (pnpoly(npol,xp,yp,0.5,-.25)) count++;
if (pnpoly(npol,xp,yp,0.5,-1.25)) count++;
if (pnpoly(npol,xp,yp,-.5,-2.5)) count++;
}
printf("count %d \n", count);
return(0);
}
LISP-LISP-LISP-LISP-LISP-LISP-LISP-LISP-LISP-LISP-LISP-LISP-LISP-LISP-LISP-LISP-LISP-LISP
(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 pt-poly-test ()
(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 -.5d0 -1.0d0
-1.0d0 -2.0d0 -2.5d0 -2.0d0 -1.5d0 -.5d0 1.0d0
1.0d0 0.0d0 -.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 -.5d0 -1.0d0 -1.5d0 -2.0d0 -2.0d0 -1.5d0
-1.0d0 -.5d0 -1.0d0 -1.0d0 -.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 -.5d0 1.5d0) (incf count))
(if (pnpoly npol xp yp .75d0 2.25d0) (incf count))
(if (pnpoly npol xp yp 0.0d0 2.01d0) (incf count))
(if (pnpoly npol xp yp -.5d0 2.5d0) (incf count))
(if (pnpoly npol xp yp -1.0d0 -.5d0) (incf count))
(if (pnpoly npol xp yp -1.5d0 .5d0) (incf count))
(if (pnpoly npol xp yp -2.25d0 -1.0d0) (incf count))
(if (pnpoly npol xp yp .5d0 -.25d0) (incf count))
(if (pnpoly npol xp yp .5d0 -1.25d0) (incf count))
(if (pnpoly npol xp yp -.5d0 -2.5d0) (incf count)))
(princ "Count ") (princ count)
count))
TCL-TCL-TCL-TCL-TCL-TCL-TCL-TCL-TCL-TCL-TCL-TCL-TCL-TCL-TCL-TCL-TCL-TCL-TCL-TCL-TCL-TCL-TCL
proc pnpoly {npol xp yp x y} {
set c 0
set j [expr $npol-1]
for {set i 0} {$i < $npol} {incr i 1} {
if {(((([lindex $yp $i] <= $y) && ($y < [lindex $yp $j])) ||
(([lindex $yp $j] <= $y) && ($y < [lindex $yp $i])))
&& ($x < (([lindex $xp $j] - [lindex $xp $i]) * ($y - [lindex $yp $i]) /
([lindex $yp $j] - [lindex $yp $i]) + [lindex $xp $i])))} {
set c [expr !$c]
}
set j $i
}
return $c
}
proc pnpolytest {} {
set count 0
set npol 20
set xp {0.0 1.0 1.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}
set 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 {set i 0} {$i<100000} {incr i} {
if {[pnpoly $npol $xp $yp 0.5 0.5]} {incr count}
if {[pnpoly $npol $xp $yp 0.5 1.5]} {incr count}
if {[pnpoly $npol $xp $yp -.5 1.5]} {incr count}
if {[pnpoly $npol $xp $yp 0.75 2.25]} {incr count}
if {[pnpoly $npol $xp $yp 0.0 2.01]} {incr count}
if {[pnpoly $npol $xp $yp -.5 2.5]} {incr count}
if {[pnpoly $npol $xp $yp -1.0 -.5]} {incr count}
if {[pnpoly $npol $xp $yp -1.5 0.5]} {incr count}
if {[pnpoly $npol $xp $yp -2.25 -1.0]} {incr count}
if {[pnpoly $npol $xp $yp 0.5 -.25]} {incr count}
if {[pnpoly $npol $xp $yp 0.5 -1.25]} {incr count}
if {[pnpoly $npol $xp $yp -0.5 -2.5]} {incr count}
}
return $count
}
PERL-PERL-PERL-PERL-PERL-PERL-PERL-PERL-PERL-PERL-PERL-PERL-PERL-PERL-PERL-PERL-PERL-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 polytest {
local($npol, $count, @xp, @yp);
$npol=20;
$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($ii = 0; $ii < 100000; $ii++) {
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,-.5,1.5)) {$count++};
if (pnpoly($npol,·@xp,·@yp,0.75,2.25)) {$count++};
if (pnpoly($npol,·@xp,·@yp,0,2.01)) {$count++};
if (pnpoly($npol,·@xp,·@yp,-.5,2.5)) {$count++};
if (pnpoly($npol,·@xp,·@yp,-1.0,-.5)) {$count++};
if (pnpoly($npol,·@xp,·@yp,-1.5,.5)) {$count++};
if (pnpoly($npol,·@xp,·@yp,-2.25,-1.0)) {$count++};
if (pnpoly($npol,·@xp,·@yp,0.5,-.25)) {$count++};
if (pnpoly($npol,·@xp,·@yp,0.5,-1.25)) {$count++};
if (pnpoly($npol,·@xp,·@yp,-.5,-2.5)) {$count++};
}
print "\n count ", $count, "\n";
}
JAVA-JAVA-JAVA-JAVA-JAVA-JAVA-JAVA-JAVA-JAVA-JAVA-JAVA-JAVA-JAVA-JAVA-JAVA-JAVA-JAVA
public class Pnpoly {
public static boolean pnpoly(int npol, double[] xp, double[] yp, double x, double y)
{
int i, j;
boolean c = false;
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;
}
public static void main(String args[]) {
int npol=20, count=0;
double[] 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};
double[] 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(int i=0;i<100000;i++) {
if (Pnpoly.pnpoly(npol,xp,yp,0.5,0.5)) count++;
if (Pnpoly.pnpoly(npol,xp,yp,0.5,1.5)) count++;
if (Pnpoly.pnpoly(npol,xp,yp,-.5,1.5)) count++;
if (Pnpoly.pnpoly(npol,xp,yp,0.75,2.25)) count++;
if (Pnpoly.pnpoly(npol,xp,yp,0,2.01)) count++;
if (Pnpoly.pnpoly(npol,xp,yp,-.5,2.5)) count++;
if (Pnpoly.pnpoly(npol,xp,yp,-1.0,-.5)) count++;
if (Pnpoly.pnpoly(npol,xp,yp,-1.5,.5)) count++;
if (Pnpoly.pnpoly(npol,xp,yp,-2.25,-1.0)) count++;
if (Pnpoly.pnpoly(npol,xp,yp,0.5,-.25)) count++;
if (Pnpoly.pnpoly(npol,xp,yp,0.5,-1.25)) count++;
if (Pnpoly.pnpoly(npol,xp,yp,-.5,-2.5)) count++;
}
System.out.println("count " + count);
}
}
PYTHON-PYTHON-PYTHON-PYTHON-PYTHON-PYTHON-PYTHON-PYTHON-PYTHON-PYTHON-PYTHON-PYTHON
def pnpoly(npol, xp, yp, x, y):
c = 0
j=npol-1
for i in range(npol):
if ((yp[i] <= y < yp[j] or yp[j] <= y < yp[i]) and
(x < (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i])):
c = not c
j = i
return c
def pnpolytest():
count=0
npol=20
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 i in range(10000):
if (pnpoly(npol,xp,yp,0.5,0.5)): count=count+1
if (pnpoly(npol,xp,yp,0.5,1.5)): count=count+1
if (pnpoly(npol,xp,yp,-.5,1.5)): count=count+1
if (pnpoly(npol,xp,yp,0.75,2.25)): count=count+1
if (pnpoly(npol,xp,yp,0,2.01)): count=count+1
if (pnpoly(npol,xp,yp,-.5,2.5)): count=count+1
if (pnpoly(npol,xp,yp,-1.0,-.5)): count=count+1
if (pnpoly(npol,xp,yp,-1.5,.5)): count=count+1
if (pnpoly(npol,xp,yp,-2.25,-1.0)): count=count+1
if (pnpoly(npol,xp,yp,0.5,-.25)): count=count+1
if (pnpoly(npol,xp,yp,0.5,-1.25)): count=count+1
if (pnpoly(npol,xp,yp,-.5,-2.5)): count=count+1
print 'count ', count
GUILE-SCHEME-GUILE-SCHEME-GUILE-SCHEME-GUILE-SCHEME-GUILE-SCHEME-GUILE-SCHEME-GUILE-SCHEME
(define pt-in-poly
(lambda (npol xp yp x y)
(let ((c #f)
(j (- npol 1)))
(do ((i 0 (+ i 1)))
((= i npol) c)
(if (and (or (and (<= (vector-ref yp i) y) (< y (vector-ref yp j)))
(and (<= (vector-ref yp j) y) (< y (vector-ref yp i))))
(< x (+ (vector-ref xp i)
(/ (* (- (vector-ref xp j) (vector-ref xp i)) (- y (vector-ref yp i)))
(- (vector-ref yp j) (vector-ref yp i))))))
(set! c (not c)))
(set! j i))
)))
(define pnpolytest
(lambda ()
(let ((npol 20)
(count 0)
(xp '#1(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 '#1(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)))
(do ((i 0 (+ i 1)))
((= i 100000))
(if (pt-in-poly npol xp yp 0.5 0.5) (set! count (+ count 1)))
(if (pt-in-poly npol xp yp 0.5 1.5) (set! count (+ count 1)))
(if (pt-in-poly npol xp yp -.5 1.5) (set! count (+ count 1)))
(if (pt-in-poly npol xp yp .75 2.25) (set! count (+ count 1)))
(if (pt-in-poly npol xp yp 0.0 2.01) (set! count (+ count 1)))
(if (pt-in-poly npol xp yp -.5 2.5) (set! count (+ count 1)))
(if (pt-in-poly npol xp yp -1.0 -.5) (set! count (+ count 1)))
(if (pt-in-poly npol xp yp -1.5 .5) (set! count (+ count 1)))
(if (pt-in-poly npol xp yp -2.25 -1.0) (set! count (+ count 1)))
(if (pt-in-poly npol xp yp .5 -.25) (set! count (+ count 1)))
(if (pt-in-poly npol xp yp .5 -1.25) (set! count (+ count 1)))
(if (pt-in-poly npol xp yp -.5 -2.5) (set! count (+ count 1)))
)
(display "count ") (write count) (newline)
count
)))
--
John D. Watton
Aluminum Company of America
Alcoa Technical Center
100 Technical Drive, Alcoa Center PA 15069
(412) 337-2165
From: Terrence M. Brannon
Subject: Re: Update: Comparing C, Lisp, Tcl, Perl, Python, Java, & Scheme (Guile) Using a Floating Point Numerical Test - Point Inside Polygon
Date:
Message-ID: <ysizrafc9u3y.fsf@bufo.usc.edu>
Did you use the Perl Data Language
(http://www.aao.gov.au/local/www/kgb/perldl/)?
With PDL the perl variable $a can hold a 1024x1024 floating point
image, it only takes 4Mb of memory to store it and expressions like
$a=sqrt($a)+2 would manipulate the whole image in a few seconds.
As a result perlDL is very fast --- for example one can mulitiply a
2048*2048 image in exactly the same time as it would take in C or
FORTRAN (0.1 sec on my SPARC). A further advantage of this is that for
simple operations (e.g. $x += 2) one can manipulate the whole array
without caring about its dimensionality.
John Watton <···········@alcoa.com> writes:
>
> Comparing C, Lisp, Tcl, Perl, Python, Java, & Scheme (Guile) Using a
> Floating Point Numerical Test - Point Inside Polygon
--
o============o Sending unsolicited commercial e-mail (UCE) to this address
Legal Notice is indication of your consent to pay me $120/hour for 1 hour
o============o minimum for professional proofreading & technical assessment.
terrence brannon * ·······@rana.usc.edu * http://rana.usc.edu:8376/~brannon
From: Fritz Heinrichmeyer
Subject: Re: Update: Comparing C, Lisp, Tcl, Perl, Python, Java, & Scheme (Guile) Using a Floating Point Numerical Test - Point Inside Polygon
Date:
Message-ID: <5ld9cg$kpq@cantaloupe.srv.cs.cmu.edu>
Here are my speed tests for ocaml (olabl variant) on a pentium 200
MHz on the mentioned piece of code.
gcc -O6 : 6.04 sec
ocaml bytecoded, with array bound checking: 79.99 sec
ocaml bytecoded, without array bound checking: 66.20 sec
ocaml native, with array bound checking: 11.33 sec
ocaml native, without array bound checking: 6.38 sec
The results fit with other experiences i made:
1. Native compiled code has roughly the same performance as good optimized
C-Code (with a fibonacci test much faster!!)
2. The bytecode has the best performance around.
The program below is an 1:1 translation, almost no functional
programming introduced (array know their length in good programming
languages :-).
(*The code below is from Wm. Randolph Franklin <···@ecse.rpi.edu>
with some minor modifications for speed.
comp.graphics.algorithms FAQ
References:
[Gems IV] pp. 24-46
[O'Rourke] pp. 233-238
[Glassner:RayTracing] *)
let pnpoly xp yp x y =
let npol = Array.length xp - 1 in
let c = ref false in
let j = ref npol in
for i = 0 to npol do
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)
then
c := not !c;
j := i
done;
!c
in
(* let main () = *)
let count = ref 0 in (* oh, oh, no good functional style *)
let xp = [| 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;-0.5;1.0;1.0;0.0;-0.5;-1.0;-0.5 |] in
let yp = [| 0.0;0.0;1.0;1.0;2.0;3.0;2.0;3.0;0.0;-0.5;
-1.0;-1.5;-2.0;-2.0;-1.5;-1.0;-0.5;-1.0;-1.0;-0.5 |] in
let incrcount () = count := !count + 1 in
for i = 0 to 99999 do
if pnpoly xp yp 0.5 0.5 then incrcount ();
if pnpoly xp yp 0.5 1.5 then incrcount ();
if pnpoly xp yp (-0.5) 1.5 then incrcount ();
if pnpoly xp yp 0.75 2.25 then incrcount ();
if pnpoly xp yp 0.0 2.01 then incrcount ();
if pnpoly xp yp (-0.5) 2.5 then incrcount ();
if pnpoly xp yp (-1.0) (-0.5) then incrcount ();
if pnpoly xp yp (-1.5) 0.5 then incrcount ();
if pnpoly xp yp (-2.25) (-1.0) then incrcount ();
if pnpoly xp yp 0.5 (-0.25) then incrcount ();
if pnpoly xp yp 0.5 (-1.25) then incrcount ();
if pnpoly xp yp (-0.5) (-2.5) then incrcount ()
done;
Printf.printf "count %d \n" !count
;;