[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