I wrote 'dispatching-for' and 'dispatching-for/fold' macros that generate a cond that dispatches to for (or fold/fold) with specific vector, list, and general versions. For example:<br><br><span style="font-family: courier new,monospace;">(define (mean data)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (dispatch-for/fold ((m-old 0.0))</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> ((i (in-naturals))</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (x data))</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (+ m-old (/ (- x m-old) (add1 i)))))</span><br style="font-family: courier new,monospace;">
<br>==><br><br><span style="font-family: courier new,monospace;">(define (mean data)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (cond (</span><span style="font-family: courier new,monospace;">(vector? data)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (for/fold ((m-old 0.0))</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">
((i (in-naturals))</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">
(x (in-vector data))</span>)<br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">
(+ m-old (/ (- x m-old) (add1 i)))))</span><span style="font-family: courier new,monospace;"><br> ((pair? data)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (for/fold ((m-old 0.0))</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">
((i (in-naturals))</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">
(x (in-list data))</span>)<br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">
(+ m-old (/ (- x m-old) (add1 i)))))</span><span style="font-family: courier new,monospace;"><br> (else</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (for/fold ((m-old 0.0))</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">
((i (in-naturals))</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">
(x data))</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">
(+ m-old (/ (- x m-old) (add1 i)))))))</span><br><br>This runs at about the same speed as the current science collection routines for vectors. Also, lists run at pretty much the same speed.<br><br>Times using 'dispatch-for' and 'dispatch-for/fold':<br>
cpu time: 250 real time: 250 gc time: 0<br>cpu time: 235 real time: 234 gc time: 0<br><br>Times using the current science collection:<br>cpu time: 250 real time: 250 gc time: 0<br>cpu time: 203 real time: 203 gc time: 0<br>
<br>The first time in each block is for the contracted version that ensures that the inputs are a sequence (or vector for the current science collection) of reals. The second time in each block is for the unchecked version that bypasses the contract check.<br>
<br>I'm not sure that any special cases other than vectors and lists make sense to break out separately.<br><br>All times were done using version 4.2.1.8-svn10sep2009, which should have Matthew's performance code.<br>
<br>Doug<br><br style="font-family: courier new,monospace;"><br><div class="gmail_quote">On Thu, Sep 10, 2009 at 10:12 AM, Doug Williams <span dir="ltr"><<a href="mailto:m.douglas.williams@gmail.com">m.douglas.williams@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div class="gmail_quote"><div class="im"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Maybe the issue of when "just in time" is. The JIT currently compiles<br>
at the granularity of `lambda', and it compiles each `lambda' only<br>
once. <br></blockquote><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
So, although `sequence-generate' may produce vector-specific operations<br>
for a given invocation of the `for' loop, the JIT produces a generic<br>
function call to the vector-specific operation (which might not be<br>
vector-specific next time around).<br></blockquote></div><div><br>So, the vector-specific lambda(s) returned by sequence-generate are optimized when they are first seen by the JIT compiler. But, there are additional optimizations (for the sequencing operation) that would not be possible within the for itself because there is not much left but generic function invocations. Specifically in the case of vectors, by having the for macro generate the increment and test of the index and the vector-refs, the JIT compiler can generate specific instructions for those operations. While, for a generic sequence that happens to be a vector, there is no alternative but to generate a call to see if more data is available and, if there is, another call to get the next element of the sequence.<br>
<br></div><div class="im"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
One possibility for improvement, then, is to change the JIT strategy to<br>
generate code later and more frequently.<br>
<div><div></div><div><br></div></div></blockquote></div></div><br>But, writing some kind of 'dispatching for' macro is probably the only near-term way of getting nearly the same performance for a generic sequence that happens to be a vector and a 'for' specific written for a vector.<br>
</blockquote></div><br>