Ah, realized that Gambit makes a difference internally between 1e25 and 10000000000000000000000000 . So added a test also for the latter.<div><br></div><div><br></div><div>Got 6,794,405 per second for |->integer| - fair enough!</div>
<div><br></div><div>And got 384,459 for |->flonum| - could be faster.</div><div><div><br></div></div><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><div><font face="courier new, monospace">> (->integer-test5)</font></div>
</div>
</div><div><div><font face="courier new, monospace">6794405.8</font></div></div><div><div><font face="courier new, monospace">> (->flonum-test5)</font></div></div><div><div><font face="courier new, monospace">384459.2</font></div>
</div><div><div><br></div></div><div><div><br></div></div><div>Def:</div><div><div><div><font face="courier new, monospace">(define (->integer-test5) (test (->integer 10000000000000000000000000)))</font></div>
</div></div><div><div><font face="courier new, monospace"><br></font></div></div><div><div><div><font face="courier new, monospace">(define (->flonum-test5) (test (->flonum 10000000000000000000000000)))</font></div>
</div></div></blockquote><div><div><br></div><div><br></div><br><div class="gmail_quote">2013/4/24 Mikael <span dir="ltr"><<a href="mailto:mikael.rcv@gmail.com" target="_blank">mikael.rcv@gmail.com</a>></span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>Dear list,</div><div><br></div><div>I was keeping this question in the back of my mind for several years so taking the occasion to reflect it now:</div>
<div><br></div><div>Here follows the result of a simple benchmark of <font face="courier new, monospace">(exact->inexact n)</font> and <font face="courier new, monospace">(exact->inexact (floor n))</font> where n is a flonum, fixnum or bignum integer, or rational.</div>
<div><br></div><div>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).</div>
<div><br></div><div>I remember a conversation on this topic like ~4y ago but don't remember any conclusion from it.</div><div><br></div><div><br></div><div>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.</div>
<div><br></div><div>To get a better idea I experimented with heap size and live percent setting with those two, and got about the same results.</div><div><br></div><div><br>If you are aware of any definition of |->integer| that would perform much better, please feel free to share!</div>
<div><br></div><div><br></div><div><br></div><div><br></div><div>Result:</div><div><br></div><div>On a laptop CPU core, here's how many of the respective operation Gambit performs per second </div><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px">
<div><font face="courier new, monospace" style="background-color:rgb(153,255,153)">->integer of an integer (fixnum) 13,804,449</font></div><div><font face="courier new, monospace" style="background-color:rgb(255,255,204)">->integer of a flonum 260,932</font><span><font face="courier new, monospace"> (perhaps </font><span style="font-family:'courier new',monospace">performs much better </span><span style="font-family:'courier new',monospace">with another definition?)</span></span></div>
<div><font face="courier new, monospace" style="background-color:rgb(153,255,153)">->integer of a rational 10,130,272</font></div><div><font face="courier new, monospace" style="background-color:rgb(255,255,204)">->integer of an integer (bignum) 598,228</font><span><font face="courier new, monospace"> (perhaps </font><span style="font-family:'courier new',monospace">performs much better </span><span style="font-family:'courier new',monospace">with another definition?)</span></span></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"><br></font></div><div><div><font face="courier new, monospace" style="background-color:rgb(153,255,153)">->flonum of an integer (fixnum) 36,550,882</font></div>
</div><div><div><font face="courier new, monospace" style="background-color:rgb(153,255,153)">->flonum of a flonum 47,756,845</font></div></div><div><div><font face="courier new, monospace" style="background-color:rgb(153,255,153)">->flonum of a rational 334,976</font></div>
</div><div><div><font face="courier new, monospace" style="background-color:rgb(153,255,153)">->flonum of an integer (bignum) 51,075,409</font></div></div></blockquote><div><br></div><div><blockquote style="margin:0 0 0 40px;border:none;padding:0px">
<div><br></div></blockquote></div><div><br></div><div>Test code:</div><div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><br></div><div><div><font face="courier new, monospace">(declare (block) (standard-bindings) (extended-bindings))</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">(define (noop) (void))</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">(define (->integer n)</font></div>
<div><font face="courier new, monospace"> (lambda ()</font></div><div><font face="courier new, monospace"> (inexact->exact (floor n))))</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">(define (->flonum n)</font></div>
<div><font face="courier new, monospace"> (lambda ()</font></div><div><font face="courier new, monospace"> (exact->inexact n)))</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">(define (test t #!optional (seconds 5))</font></div>
<div><font face="courier new, monospace"> (let* ((at 0)</font></div><div><font face="courier new, monospace"> (th (thread-start! (make-thread (lambda () (let loop ()</font></div><div><font face="courier new, monospace"> (t)</font></div>
<div><font face="courier new, monospace"> (set! at (fx+ at 1))</font></div><div><font face="courier new, monospace"> (loop)))))))</font></div>
<div><font face="courier new, monospace"> (thread-sleep! seconds)</font></div><div><font face="courier new, monospace"> (let ((r at))</font></div><div><font face="courier new, monospace"> (thread-terminate! th)</font></div>
<div><font face="courier new, monospace"> (exact->inexact (/ r seconds)))))</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">(define (noop-test) (test noop))</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">(define (->integer-test1) (test (->integer 5 )))</font></div><div><font face="courier new, monospace">(define (->integer-test2) (test (->integer 5. )))</font></div>
<div><font face="courier new, monospace">(define (->integer-test3) (test (->integer 10/7)))</font></div><div><font face="courier new, monospace">(define (->integer-test4) (test (->integer 1e25)))</font></div>
<div>
<font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">(define (->flonum-test1) (test (->flonum 5 )))</font></div><div><font face="courier new, monospace">(define (->flonum-test2) (test (->flonum 5. )))</font></div>
<div><font face="courier new, monospace">(define (->flonum-test3) (test (->flonum 10/7)))</font></div><div><font face="courier new, monospace">(define (->flonum-test4) (test (->flonum 1e25)))</font></div></div>
</div><div><br></div></blockquote><div><br></div><div><div>Test output:</div><div><br></div><div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><font face="courier new, monospace">> (time (noop-test))</font></div>
<div><font face="courier new, monospace">(time (noop-test))</font></div><div><font face="courier new, monospace"> 5040 ms real time</font></div><div><font face="courier new, monospace"> 4932 ms cpu time (4896 user, 36 system)</font></div>
<div><font face="courier new, monospace"> no collections</font></div><div><font face="courier new, monospace"> 2112 bytes allocated</font></div><div><font face="courier new, monospace"> 6 minor faults</font></div>
<div><font face="courier new, monospace"> no major faults</font></div><div><font face="courier new, monospace">57985446.4</font></div><div><font face="courier new, monospace">> (time (->integer-test1))</font></div>
<div><font face="courier new, monospace">(time (->integer-test1))</font></div><div><font face="courier new, monospace"> 5019 ms real time</font></div><div><font face="courier new, monospace"> 4884 ms cpu time (4872 user, 12 system)</font></div>
<div><font face="courier new, monospace"> no collections</font></div><div><font face="courier new, monospace"> 1232 bytes allocated</font></div><div><font face="courier new, monospace"> no minor faults</font></div>
<div><font face="courier new, monospace"> no major faults</font></div><div><font face="courier new, monospace">13804449.</font></div><div><font face="courier new, monospace">> (time (->integer-test2))</font></div>
<div><font face="courier new, monospace">(time (->integer-test2))</font></div><div><font face="courier new, monospace"> 5000 ms real time</font></div><div><font face="courier new, monospace"> 4792 ms cpu time (4656 user, 136 system)</font></div>
<div><font face="courier new, monospace"> 81 collections accounting for 187 ms real time (120 user, 52 system)</font></div><div><font face="courier new, monospace"> 1607420656 bytes allocated</font></div><div><font face="courier new, monospace"> 5110 minor faults</font></div>
<div><font face="courier new, monospace"> no major faults</font></div><div><font face="courier new, monospace">260932.6</font></div><div><font face="courier new, monospace">> (time (->integer-test3))</font></div>
<div><font face="courier new, monospace">(time (->integer-test3))</font></div><div><font face="courier new, monospace"> 5015 ms real time</font></div><div><font face="courier new, monospace"> 4888 ms cpu time (4872 user, 16 system)</font></div>
<div><font face="courier new, monospace"> no collections</font></div><div><font face="courier new, monospace"> 2240 bytes allocated</font></div><div><font face="courier new, monospace"> no minor faults</font></div>
<div><font face="courier new, monospace"> no major faults</font></div><div><font face="courier new, monospace">10130272.8</font></div><div><font face="courier new, monospace">> (time (->integer-test4))</font></div>
<div><font face="courier new, monospace">(time (->integer-test4))</font></div><div><font face="courier new, monospace"> 5003 ms real time</font></div><div><font face="courier new, monospace"> 4680 ms cpu time (4536 user, 144 system)</font></div>
<div><font face="courier new, monospace"> 158 collections accounting for 401 ms real time (304 user, 60 system)</font></div><div><font face="courier new, monospace"> 3110877424 bytes allocated</font></div><div><font face="courier new, monospace"> no minor faults</font></div>
<div><font face="courier new, monospace"> no major faults</font></div><div><font face="courier new, monospace">598228.8</font></div><div><font face="courier new, monospace">> (time (->flonum-test1))</font></div>
<div>
<font face="courier new, monospace">(time (->flonum-test1))</font></div><div><font face="courier new, monospace"> 5011 ms real time</font></div><div><font face="courier new, monospace"> 4740 ms cpu time (4460 user, 280 system)</font></div>
<div><font face="courier new, monospace"> 297 collections accounting for 736 ms real time (524 user, 124 system)</font></div><div><font face="courier new, monospace"> 5848140864 bytes allocated</font></div><div><font face="courier new, monospace"> no minor faults</font></div>
<div><font face="courier new, monospace"> no major faults</font></div><div><font face="courier new, monospace">36550882.2</font></div><div><font face="courier new, monospace">> (time (->flonum-test2))</font></div>
<div><font face="courier new, monospace">(time (->flonum-test2))</font></div><div><font face="courier new, monospace"> 5001 ms real time</font></div><div><font face="courier new, monospace"> 4840 ms cpu time (4800 user, 40 system)</font></div>
<div><font face="courier new, monospace"> no collections</font></div><div><font face="courier new, monospace"> 2088 bytes allocated</font></div><div><font face="courier new, monospace"> no minor faults</font></div>
<div><font face="courier new, monospace"> no major faults</font></div><div><font face="courier new, monospace">47756845.8</font></div><div><font face="courier new, monospace">> (time (->flonum-test3))</font></div>
<div><font face="courier new, monospace">(time (->flonum-test3))</font></div><div><font face="courier new, monospace"> 5005 ms real time</font></div><div><font face="courier new, monospace"> 4972 ms cpu time (4920 user, 52 system)</font></div>
<div><font face="courier new, monospace"> 65 collections accounting for 147 ms real time (120 user, 16 system)</font></div><div><font face="courier new, monospace"> 1286350504 bytes allocated</font></div><div><font face="courier new, monospace"> no minor faults</font></div>
<div><font face="courier new, monospace"> no major faults</font></div><div><font face="courier new, monospace">334976.6</font></div><div><font face="courier new, monospace">> (time (->flonum-test4))</font></div>
<div>
<font face="courier new, monospace">(time (->flonum-test4))</font></div><div><font face="courier new, monospace"> 5002 ms real time</font></div><div><font face="courier new, monospace"> 4876 ms cpu time (4848 user, 28 system)</font></div>
<div><font face="courier new, monospace"> no collections</font></div><div><font face="courier new, monospace"> 2080 bytes allocated</font></div><div><font face="courier new, monospace"> no minor faults</font></div>
<div><font face="courier new, monospace"> no major faults</font></div><div><font face="courier new, monospace">51075409.8</font></div><div><font face="courier new, monospace"><br></font></div></blockquote></div></div>
<div>
<br></div><br><div class="gmail_quote">2013/4/24 Bradley Lucier <span dir="ltr"><<a href="mailto:lucier@math.purdue.edu" target="_blank">lucier@math.purdue.edu</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div text="#000000" bgcolor="#FFFFFF"><div>
<div><tt>On 04/24/2013 01:33 PM, Mikael
wrote:</tt><tt><br>
</tt></div>
<blockquote type="cite"><tt>Hi Brad!</tt><tt><br>
</tt><tt><br>
</tt>
<div class="gmail_quote"><tt>2013/4/24 Bradley Lucier </tt><tt><span dir="ltr"><<a href="mailto:lucier@math.purdue.edu" target="_blank">lucier@math.purdue.edu</a>></span></tt><tt><br>
</tt>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><tt>On 04/24/2013 12:37 PM, Zhen Shen wrote:</tt></div>
</blockquote>
<div><tt><br>
</tt></div>
<div><tt>[...]</tt></div>
<div><tt> </tt></div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><tt>
> Now, doing (declare (flonum)) at the top level, does
this stop gambit</tt><tt><br>
</tt><tt>
> from boxing flonums across function calls?</tt><tt><br>
</tt>
<tt><br>
</tt>
</div>
<tt>No. Gambit keeps flonums unboxed inside a basic block,
whenever there's</tt><tt><br>
</tt><tt>
a jump (or the possibility of a jump), Gambit boxes up all
the</tt><tt><br>
</tt><tt>
still-needed flonums.</tt><tt><br>
</tt></blockquote>
<div><tt><br>
</tt></div>
<div><tt>What about fixnums, would they remain unboxed in a
loop?</tt></div>
</div>
</blockquote>
<tt><br>
</tt></div><tt>Yes. Fixnums are always "immediate" (not boxed) values.</tt><div><tt><br>
</tt><tt><br>
</tt>
<blockquote type="cite">
<div class="gmail_quote">
<div><tt><br>
</tt></div>
<div><tt>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)?</tt><tt><br>
</tt></div>
</div>
</blockquote>
<tt><br>
</tt></div><tt>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.</tt><tt> (With generic operations,
flonums are boxed even in a basic block.)<br>
</tt><tt><br>
</tt><tt>Or, you can use an f64vector as an explicit "box" for your
flonum and write monstrous code like this.</tt><tt><br>
</tt><tt><br>
</tt><tt>(define (Array-sum a)</tt><tt><br>
</tt><tt> (f64vector-ref (Array-reduce (lambda (result y)</tt><tt><br>
</tt><tt> (f64vector-set! result 0
(fl+ (f64vector-ref result 0) y))</tt><tt><br>
</tt><tt> result)</tt><tt><br>
</tt><tt> (f64vector 0.)</tt><tt><br>
</tt><tt> a)</tt><tt><br>
</tt><tt> 0))</tt><tt><br>
<br>
Brad<br>
</tt>
</div>
</blockquote></div><br></div>
</blockquote></div><br></div>