[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 15:32:11 EDT 2013


Ah, realized that Gambit makes a difference internally between 1e25
and 10000000000000000000000000 . So added a test also for the latter.


Got 6,794,405 per second for |->integer| - fair enough!

And got 384,459 for |->flonum| - could be faster.


> (->integer-test5)
 6794405.8
> (->flonum-test5)
384459.2


Def:
(define (->integer-test5) (test (->integer 10000000000000000000000000)))

(define (->flonum-test5) (test (->flonum 10000000000000000000000000)))




2013/4/24 Mikael <mikael.rcv at gmail.com>

> Dear list,
>
> I was keeping this question in the back of my mind for several years so
> taking the occasion to reflect it now:
>
> Here follows the result of a simple benchmark of (exact->inexact n) and (exact->inexact
> (floor n)) where n is a flonum, fixnum or bignum integer, or rational.
>
> The code was executed in compiled form, with both safe and
> interrupts-enabled set and without any consideration to C compiler flags
> beyond -O1 , to reflect the environment of a typical application (not for
> instance a specialized number crunching environment).
>
> I remember a conversation on this topic like ~4y ago but don't remember
> any conclusion from it.
>
>
> Looking at these numbers, I think they're great and all you can ask for,
> with two exceptions, being to-integer conversion of a flonum or integer
> bignum.
>
> To get a better idea I experimented with heap size and live percent
> setting with those two, and got about the same results.
>
>
> If you are aware of any definition of |->integer| that would perform much
> better, please feel free to share!
>
>
>
>
> Result:
>
> On a laptop CPU core, here's how many of the respective operation Gambit
> performs per second
>
> ->integer of an integer (fixnum) 13,804,449
> ->integer of a flonum               260,932 (perhaps performs much better with
> another definition?)
> ->integer of a rational          10,130,272
> ->integer of an integer (bignum)    598,228 (perhaps performs much better with
> another definition?)
>
>
> ->flonum of an integer (fixnum)  36,550,882
> ->flonum of a flonum             47,756,845
> ->flonum of a rational              334,976
> ->flonum of an integer (bignum)  51,075,409
>
>
>
>
> Test code:
>
>
> (declare (block) (standard-bindings) (extended-bindings))
>
> (define (noop) (void))
>
> (define (->integer n)
>   (lambda ()
>     (inexact->exact (floor n))))
>
> (define (->flonum n)
>   (lambda ()
>     (exact->inexact n)))
>
> (define (test t #!optional (seconds 5))
>   (let* ((at 0)
>          (th (thread-start! (make-thread (lambda () (let loop ()
>                                                       (t)
>                                                       (set! at (fx+ at 1))
>                                                       (loop)))))))
>     (thread-sleep! seconds)
>     (let ((r at))
>       (thread-terminate! th)
>       (exact->inexact (/ r seconds)))))
>
>
> (define (noop-test) (test noop))
>
> (define (->integer-test1) (test (->integer 5   )))
> (define (->integer-test2) (test (->integer 5.  )))
> (define (->integer-test3) (test (->integer 10/7)))
> (define (->integer-test4) (test (->integer 1e25)))
>
> (define (->flonum-test1) (test (->flonum 5   )))
> (define (->flonum-test2) (test (->flonum 5.  )))
> (define (->flonum-test3) (test (->flonum 10/7)))
> (define (->flonum-test4) (test (->flonum 1e25)))
>
>
> Test output:
>
> > (time (noop-test))
> (time (noop-test))
>     5040 ms real time
>     4932 ms cpu time (4896 user, 36 system)
>     no collections
>     2112 bytes allocated
>     6 minor faults
>     no major faults
> 57985446.4
> > (time (->integer-test1))
> (time (->integer-test1))
>     5019 ms real time
>     4884 ms cpu time (4872 user, 12 system)
>     no collections
>     1232 bytes allocated
>     no minor faults
>     no major faults
> 13804449.
> > (time (->integer-test2))
> (time (->integer-test2))
>     5000 ms real time
>     4792 ms cpu time (4656 user, 136 system)
>     81 collections accounting for 187 ms real time (120 user, 52 system)
>     1607420656 bytes allocated
>     5110 minor faults
>     no major faults
> 260932.6
> > (time (->integer-test3))
> (time (->integer-test3))
>     5015 ms real time
>     4888 ms cpu time (4872 user, 16 system)
>     no collections
>     2240 bytes allocated
>     no minor faults
>     no major faults
> 10130272.8
> > (time (->integer-test4))
> (time (->integer-test4))
>     5003 ms real time
>     4680 ms cpu time (4536 user, 144 system)
>     158 collections accounting for 401 ms real time (304 user, 60 system)
>     3110877424 bytes allocated
>     no minor faults
>     no major faults
> 598228.8
> > (time (->flonum-test1))
>  (time (->flonum-test1))
>     5011 ms real time
>     4740 ms cpu time (4460 user, 280 system)
>     297 collections accounting for 736 ms real time (524 user, 124 system)
>     5848140864 bytes allocated
>     no minor faults
>     no major faults
> 36550882.2
> > (time (->flonum-test2))
> (time (->flonum-test2))
>     5001 ms real time
>     4840 ms cpu time (4800 user, 40 system)
>     no collections
>     2088 bytes allocated
>     no minor faults
>     no major faults
> 47756845.8
> > (time (->flonum-test3))
> (time (->flonum-test3))
>     5005 ms real time
>     4972 ms cpu time (4920 user, 52 system)
>     65 collections accounting for 147 ms real time (120 user, 16 system)
>     1286350504 bytes allocated
>     no minor faults
>     no major faults
> 334976.6
> > (time (->flonum-test4))
>  (time (->flonum-test4))
>     5002 ms real time
>     4876 ms cpu time (4848 user, 28 system)
>     no collections
>     2080 bytes allocated
>     no minor faults
>     no major faults
> 51075409.8
>
>
>
> 2013/4/24 Bradley Lucier <lucier at math.purdue.edu>
>
>>  On 04/24/2013 01:33 PM, Mikael wrote:
>>
>> Hi Brad!
>>
>>  2013/4/24 Bradley Lucier <lucier at math.purdue.edu>
>>
>>> On 04/24/2013 12:37 PM, Zhen Shen wrote:
>>>
>>
>>  [...]
>>
>>
>>>  > Now, doing (declare (flonum)) at the top level, does this stop gambit
>>>  > from boxing flonums across function calls?
>>>
>>>  No.  Gambit keeps flonums unboxed inside a basic block, whenever
>>> there's
>>>  a jump (or the possibility of a jump), Gambit boxes up all the
>>>  still-needed flonums.
>>>
>>
>>  What about fixnums, would they remain unboxed in a loop?
>>
>>
>> Yes.  Fixnums are always "immediate" (not boxed) values.
>>
>>
>>
>>  Also btw, are there any tricks that can be applied to make it keep
>> flonums and fixnums unboxed in loops, like, (declare (not
>> interrupts-enabled)) or (not safe)?
>>
>>
>> Use (declare (not safe)) and flonum-specific operations to keep flonums
>> unboxed in a basic block.  There's no way to keep them unboxed across jumps.
>> (With generic operations, flonums are boxed even in a basic block.)
>>
>> Or, you can use an f64vector as an explicit "box" for your flonum and
>> write monstrous code like this.
>>
>> (define (Array-sum a)
>>   (f64vector-ref (Array-reduce (lambda (result y)
>>                                  (f64vector-set! result 0 (fl+
>> (f64vector-ref result 0) y))
>>                                  result)
>>                                (f64vector 0.)
>>                                a)
>>                    0))
>>
>> Brad
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.iro.umontreal.ca/pipermail/gambit-list/attachments/20130424/e0caae49/attachment.htm>


More information about the Gambit-list mailing list