<br><br><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">
    <tt>OK, data is good.</tt><tt><br>
    </tt><tt><br>
    </tt><tt>Here is what Gambit expands your code to, with some
      annotations:</tt><tt><br>
    </tt><tt><br>
    </tt>
    <blockquote><tt>heine:~/Downloads> gsc -c -expansion
        conversion.scm </tt><tt><br>
      </tt><tt>Expansion:</tt><tt><br>
      </tt><tt><br>
      </tt><tt>(define noop (lambda () #!void))</tt><tt><br>
      </tt><tt><br>
      </tt></blockquote>
    <tt>The following implies that gsc could expand (floor n) better as:</tt><tt><br>
    </tt><tt><br>
    </tt><tt>(cond ((fixnum? n) n)</tt><tt><br>
    </tt><tt>      (</tt><tt>(and ('#<procedure #2 ##flonum?> n)
      ('#<procedure #3 ##flfinite?> n))</tt><tt> </tt><tt>('#<procedure
      #4 ##flfloor> n))</tt><tt><br>
    </tt><tt>      (else</tt><tt> </tt><tt>('#<procedure #5
      floor> n))))</tt><tt><br>
    </tt><tt><br>
    </tt><tt>and it could expand inexact->exact better </tt><tt>(after
      defining flfixnum?) as</tt><tt><br>
    </tt><tt><br>
    </tt><tt>(cond ((fixnum? </tt><tt>n) n)</tt><tt><br>
    </tt><tt>      ((and (flonum? n) (flinteger? n)</tt><tt> (flfixnum?
      n)) (flonum->fixnum n))</tt><tt><br>
    </tt><tt>      (else (<inexact->exact> n))</tt></div></blockquote><div><br></div><div>Wait, is this a feature suggestion for Gambit, did I understand you right by that?</div><div><br></div><div>(As in, currently Gambit expands it another way and now you suggest this particular way that you've given here)</div>

<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div text="#000000" bgcolor="#FFFFFF"><blockquote><tt>(define ->integer</tt><tt><br>
      </tt><tt>  (lambda (n)</tt><tt><br>
      </tt><tt>    (lambda ()</tt><tt><br>
      </tt><tt>      (let ((temp.5 (if (and ('#<procedure #2
        ##flonum?> n) ('#<procedure #3 ##flfinite?> n))</tt><tt><br>
      </tt><tt>                        ('#<procedure #4 ##flfloor>
        n)</tt><tt><br>
      </tt><tt>                        ('#<procedure #5 floor>
        n))))</tt><tt><br>
      </tt><tt>        (if ('#<procedure #6 ##fixnum?> temp.5)
        temp.5 ('#<procedure #7 inexact->exact> temp.5))))))</tt><tt><br>
      </tt><tt><br>
      </tt><tt>(define ->flonum</tt><tt><br>
      </tt><tt>  (lambda (n)</tt><tt><br>
      </tt><tt>    (lambda ()</tt><tt><br>
      </tt><tt>      (if ('#<procedure #6 ##fixnum?> n)</tt><tt><br>
      </tt><tt>          ('#<procedure #8 ##fl<-fx> n)</tt><tt><br>
      </tt><tt>          (if ('#<procedure #2 ##flonum?> n) n
        ('#<procedure #9 exact->inexact> n))))))</tt><tt><br>
      </tt><tt><br>
      </tt></blockquote>
    <tt>This following machinery seems pretty heavy.  I'd suggest</tt><tt><br>
    </tt><tt><br>
    </tt><tt>(define (test t #!optional (seconds 1.))</tt><tt><br>
    </tt><tt>  (let loop ((n 1))</tt><tt><br>
    </tt><tt>    (let ((start-time (cpu-time)))</tt><tt><br>
    </tt><tt>      (do ((i 0 (fx+ i 1)))</tt><tt><br>
    </tt><tt>      ((fx= i n))</tt><tt><br>
    </tt><tt>    (t))</tt><tt><br>
    </tt><tt>      (let ((end-time (cpu-time)))</tt><tt><br>
    </tt><tt>    (if (<= seconds (fl- end-time start-time))</tt><tt><br>
    </tt><tt>        (pp (/ n (fl- end-time start-time)))</tt><tt><br>
    </tt><tt>        (loop (fx* n 2)))))))</tt><tt><br>
    </tt>
    <blockquote><tt><br>
      </tt><tt>(define test</tt><tt><br>
      </tt><tt>  (lambda (t #!optional (seconds 5))</tt><tt><br>
      </tt><tt>    (let ((at ('#<procedure #10 ##box> 0)))</tt><tt><br>
      </tt><tt>      (let ((th (thread-start!</tt><tt><br>
      </tt><tt>                 (make-thread</tt><tt><br>
      </tt><tt>                  (lambda ()</tt><tt><br>
      </tt><tt>                    (letrec ((loop (lambda (t at)</tt><tt><br>
      </tt><tt>                                     (let ((begin-temp.1
        (t)))</tt><tt><br>
      </tt><tt>                                       (let
        ((begin-temp.0</tt><tt><br>
      </tt><tt>                                             
        ('#<procedure #11 ##set-box!></tt><tt><br>
      </tt><tt>                                               at</tt><tt><br>
      </tt><tt>                                               (let
        ((temp.7 ('#<procedure #12 ##unbox> at)))</tt><tt><br>
      </tt><tt>                                                 (if
        ('#<procedure #6 ##fixnum?> temp.7)</tt><tt><br>
      </tt><tt>                                                     (let
        ((temp.9 ('#<procedure #13 ##fx+?> temp.7 1)))</tt><tt><br>
      </tt><tt>                                                      
        (if temp.9 temp.9 ('#<procedure #14 fx+> temp.7 1)))</tt><tt><br>
      </tt><tt>                                                    
        ('#<procedure #14 fx+> temp.7 1))))))</tt><tt><br>
      </tt><tt>                                         (loop t at))))))</tt><tt><br>
      </tt><tt>                      (loop t at)))))))</tt><tt><br>
      </tt><tt>        (let ((begin-temp.3 (thread-sleep! seconds)))</tt><tt><br>
      </tt><tt>          (let ((r ('#<procedure #12 ##unbox> at)))</tt><tt><br>
      </tt><tt>            (let ((begin-temp.2 (thread-terminate! th)))</tt><tt><br>
      </tt><tt>              (let ((temp.12 (if (and ('#<procedure #2
        ##flonum?> seconds) ('#<procedure #2 ##flonum?> r))</tt><tt><br>
      </tt><tt>                                 ('#<procedure #15
        ##fl/> r seconds)</tt><tt><br>
      </tt><tt>                                 ('#<procedure #16
        /> r seconds))))</tt><tt><br>
      </tt><tt>                (if ('#<procedure #6 ##fixnum?>
        temp.12)</tt><tt><br>
      </tt><tt>                    ('#<procedure #8 ##fl<-fx>
        temp.12)</tt><tt><br>
      </tt><tt>                    (if ('#<procedure #2 ##flonum?>
        temp.12) temp.12 ('#<procedure #9 exact->inexact>
        temp.12)))))))))))</tt><tt><br>
      </tt><tt><br>
      </tt></blockquote>
    <tt>With that, my rates are (first for void, then the four
      ->integer, then the four ->flon</tt><tt>um):</tt><tt><br>
    </tt><tt><br>
    </tt><tt>76082403.02475469</tt><tt><br>
    </tt><tt><br>
    </tt><tt>18077766.69130593</tt><tt><br>
    </tt><tt style="background-color:rgb(255,255,204)">2113932</tt><tt style="background-color:rgb(255,255,255)">.395354323</tt><tt><br>
    </tt><tt>12632656.242117403</tt><tt><br>
    </tt><tt><span style="background-color:rgb(255,255,255)">1560283</span>.434666285</tt><tt><br>
    </tt><tt><br>
    </tt><tt>34377410.006859235</tt><tt><br>
    </tt><tt>69323006.15509051</tt><tt><br>
    </tt><tt>1230645.7282318561</tt><tt><br>
    </tt><tt>69180045.37858963</tt><tt><br>
    </tt><tt><br>
    </tt><tt>And, with (</tt><tt>declare (not safe)) I get</tt><tt><br>
    </tt><tt><br>
    </tt><tt>105510445.88390666</tt><tt><br>
    </tt><tt><br>
    </tt><tt>18807367.927219782</tt><tt><br>
    </tt><tt style="background-color:rgb(255,255,204)">2444080</tt><tt style="background-color:rgb(255,255,255)">.701261633</tt><tt><br>
    </tt><tt>13230418.609566122</tt><tt><br>
    </tt><tt><span style="background-color:rgb(255,255,255)">1569627</span>.036643679</tt><tt><br>
    </tt><tt><br>
    </tt><tt>47124065.98183112</tt><tt><br>
    </tt><tt>92942772.26488659</tt><tt><br>
    </tt><tt>1327228.230636181</tt><tt><br>
    </tt><tt>92942772.26488681</tt></div></blockquote><div><br></div><div><br></div></div><div>Basically, nice numbers!</div><div><br></div><div><span style="font-size:13px;background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif"><br>

</span></div><div><br></div><div>Numbers that are in the millions are good really.</div><div><br></div><div>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; .</div>

<div><br></div><div>I tried it out in C and got 47,619,047 per second, code below.</div><div><br></div><div>Now, Gambit does lots of typechecking and boxing and stuff, though shouldn't like 5-10 million per second be reachable?</div>

<div><br></div><div>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.</div>

<div><br></div><div>Addressed this because I thought it's like a generally relevant thing.</div><div><br></div><div><br></div><div><br></div><div>Brgds</div><div><br></div><div><br></div><div>C test:</div><div><br></div>

<blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><font face="courier new, monospace">#include <stdio.h></font></div></div><div><div><font face="courier new, monospace">#include <stdlib.h></font></div>

</div><div><div><font face="courier new, monospace"><br></font></div></div><div><div><font face="courier new, monospace">int main() {</font></div></div><div><div><font face="courier new, monospace"><span class="Apple-tab-span" style="white-space:pre">       </span>double d = (double)rand()/100.0;</font></div>

</div><div><div><font face="courier new, monospace"><span class="Apple-tab-span" style="white-space:pre">   </span>int x;</font></div></div><div><div><font face="courier new, monospace"><span class="Apple-tab-span" style="white-space:pre">       </span>int i;</font></div>

</div><div><div><font face="courier new, monospace"><span class="Apple-tab-span" style="white-space:pre">   </span>for (i = 0; i < 1000000000; i++) {</font></div></div><div><div><font face="courier new, monospace"><span class="Apple-tab-span" style="white-space:pre">                </span>x = (int) d;</font></div>

</div><div><div><font face="courier new, monospace"><span class="Apple-tab-span" style="white-space:pre">   </span>}</font></div></div><div><div><font face="courier new, monospace">}</font></div></div></blockquote><div><br>

</div><div>g++ cfile.c; time ./a.out</div>