[gambit-list] Simple benchmark of |->integer| and |->flonum| on integer, flonum and rational input. For the further if you have any idea of a definition faster than (inexact->exact (floor n)) feel free to share :)
Mikael
mikael.rcv at gmail.com
Wed Apr 24 17:17:37 EDT 2013
2013/4/24 Bradley Lucier <lucier at math.purdue.edu>
> OK, data is good.
>
> Here is what Gambit expands your code to, with some annotations:
>
> heine:~/Downloads> gsc -c -expansion conversion.scm
> Expansion:
>
> (define noop (lambda () #!void))
>
> The following implies that gsc could expand (floor n) better as:
>
> (cond ((fixnum? n) n)
> ((and ('#<procedure #2 ##flonum?> n) ('#<procedure #3 ##flfinite?>
> n)) ('#<procedure #4 ##flfloor> n))
> (else ('#<procedure #5 floor> n))))
>
> and it could expand inexact->exact better (after defining flfixnum?) as
>
> (cond ((fixnum? n) n)
> ((and (flonum? n) (flinteger? n) (flfixnum? n)) (flonum->fixnum n))
> (else (<inexact->exact> n))
>
Wait, is this a feature suggestion for Gambit, did I understand you right
by that?
(As in, currently Gambit expands it another way and now you suggest this
particular way that you've given here)
> (define ->integer
> (lambda (n)
> (lambda ()
> (let ((temp.5 (if (and ('#<procedure #2 ##flonum?> n) ('#<procedure
> #3 ##flfinite?> n))
> ('#<procedure #4 ##flfloor> n)
> ('#<procedure #5 floor> n))))
> (if ('#<procedure #6 ##fixnum?> temp.5) temp.5 ('#<procedure #7
> inexact->exact> temp.5))))))
>
> (define ->flonum
> (lambda (n)
> (lambda ()
> (if ('#<procedure #6 ##fixnum?> n)
> ('#<procedure #8 ##fl<-fx> n)
> (if ('#<procedure #2 ##flonum?> n) n ('#<procedure #9
> exact->inexact> n))))))
>
> This following machinery seems pretty heavy. I'd suggest
>
> (define (test t #!optional (seconds 1.))
> (let loop ((n 1))
> (let ((start-time (cpu-time)))
> (do ((i 0 (fx+ i 1)))
> ((fx= i n))
> (t))
> (let ((end-time (cpu-time)))
> (if (<= seconds (fl- end-time start-time))
> (pp (/ n (fl- end-time start-time)))
> (loop (fx* n 2)))))))
>
>
> (define test
> (lambda (t #!optional (seconds 5))
> (let ((at ('#<procedure #10 ##box> 0)))
> (let ((th (thread-start!
> (make-thread
> (lambda ()
> (letrec ((loop (lambda (t at)
> (let ((begin-temp.1 (t)))
> (let ((begin-temp.0
> ('#<procedure #11 ##set-box!>
> at
> (let ((temp.7 ('#<procedure
> #12 ##unbox> at)))
> (if ('#<procedure #6
> ##fixnum?> temp.7)
> (let ((temp.9
> ('#<procedure #13 ##fx+?> temp.7 1)))
> (if temp.9 temp.9
> ('#<procedure #14 fx+> temp.7 1)))
> ('#<procedure #14
> fx+> temp.7 1))))))
> (loop t at))))))
> (loop t at)))))))
> (let ((begin-temp.3 (thread-sleep! seconds)))
> (let ((r ('#<procedure #12 ##unbox> at)))
> (let ((begin-temp.2 (thread-terminate! th)))
> (let ((temp.12 (if (and ('#<procedure #2 ##flonum?> seconds)
> ('#<procedure #2 ##flonum?> r))
> ('#<procedure #15 ##fl/> r seconds)
> ('#<procedure #16 /> r seconds))))
> (if ('#<procedure #6 ##fixnum?> temp.12)
> ('#<procedure #8 ##fl<-fx> temp.12)
> (if ('#<procedure #2 ##flonum?> temp.12) temp.12
> ('#<procedure #9 exact->inexact> temp.12)))))))))))
>
> With that, my rates are (first for void, then the four ->integer, then
> the four ->flonum):
>
> 76082403.02475469
>
> 18077766.69130593
> 2113932.395354323
> 12632656.242117403
> 1560283.434666285
>
> 34377410.006859235
> 69323006.15509051
> 1230645.7282318561
> 69180045.37858963
>
> And, with (declare (not safe)) I get
>
> 105510445.88390666
>
> 18807367.927219782
> 2444080.701261633
> 13230418.609566122
> 1569627.036643679
>
> 47124065.98183112
> 92942772.26488659
> 1327228.230636181
> 92942772.26488681
>
Basically, nice numbers!
Numbers that are in the millions are good really.
I'd love to see the flonum to integer speed a bit higher (yellow above), I
mean in C that's just double d; int i = (int) d; .
I tried it out in C and got 47,619,047 per second, code below.
Now, Gambit does lots of typechecking and boxing and stuff, though
shouldn't like 5-10 million per second be reachable?
That I got 10-50 million per second of the other operations that do
basically the same thing as this in Gambit led me to think that there might
be some other definition of |->integer| that could get to this result,
though not clear right now what that definition would be.
Addressed this because I thought it's like a generally relevant thing.
Brgds
C test:
#include <stdio.h>
#include <stdlib.h>
int main() {
double d = (double)rand()/100.0;
int x;
int i;
for (i = 0; i < 1000000000; i++) {
x = (int) d;
}
}
g++ cfile.c; time ./a.out
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.iro.umontreal.ca/pipermail/gambit-list/attachments/20130425/0e5c9986/attachment.htm>
More information about the Gambit-list
mailing list