<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>Thanks, Zoltan pointed out that the performance under LLVM is pretty good, so I probably did not have LLVM enabled. &nbsp;Indeed I checked and found that to be the case (my bad). &nbsp;As for the pattern you mention, aware that mono is able to avoid checks in that scenario. &nbsp;</div><div><br></div><div>More often then not, though, I am dealing with structures that use double[] with allocations &gt; the span of interest (as the series grow in size). &nbsp;So I usually have to rely on a variable that indicates size rather than array.Length. &nbsp; I could have used in this test though.</div><div><br></div><div>It would be nice (and seemingly would be straightforward) if the JIT was able to recognize:</div><div><br></div><div><ol class="MailOutline"><li>the len variable is invariant / locally scoped with respect to the loop</li><li>can have 2 code paths:</li><ol><li>one for if the condition will be within bounds (can avoid bounds checking)</li><li>one for if the condition is either not in bounds or cannot be determined to be invariant (hence should do the normal bounds checking)</li></ol></ol><div><br></div></div><div>I suppose a crutch to work around this, playing to mono's jit would be:</div><div><br></div><div>for (int i = 0 ; i &lt; array.Length ; i++)</div><div>{</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>if (i &lt; &lt;length expression&gt;)</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>&lt;do computation on array[i]&gt;</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>else</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>break;</div><div>}</div><div><br></div><div>The cost of the extra condition might outweigh the benefit (I haven't studied the branch cycle times to know). &nbsp; &nbsp;Better would be:</div><div><br></div><div>if (&lt;length expression&gt; &lt;= array.Length AND invariant)</div><div>{</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>for (int i = 0 ; i &lt; &lt;length expression&gt; ; i++)</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>{</div><div><span class="Apple-tab-span" style="white-space: pre; ">                </span>&lt;do computation on array[i] without checks&gt;</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div>}</div><div>else</div><div>{</div><div><span class="Apple-tab-span" style="white-space: pre; ">        </span>for (int i = 0 ; i &lt; &lt;length expression&gt; ; i++)</div><div><span class="Apple-tab-span" style="white-space: pre; ">        </span>{</div><div><span class="Apple-tab-span" style="white-space: pre; ">                </span>&lt;do computation on array[i] with checks&gt;</div><div><span class="Apple-tab-span" style="white-space: pre; ">        </span>}</div><div>}</div><div><br></div><div>It is too bad that one cannot declare a primitive expression to be locally const in C#. &nbsp;In java one can do something like:</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>final int len = &lt;some expression&gt;</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>for (int i = 0 ; i &lt; len ; i++) ...</div><div><br></div><div>OR in C#</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>const int len = &lt;some expression&gt; &nbsp; &nbsp;(error if the expression refers to functions or variables)</div><div><br></div><div>With an explicit notion of invariance could simplify the decision for the JIT.</div><div><br></div><br><div><div>On Nov 20, 2011, at 11:38 AM, Konrad M. KruczyƄski wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div>Hi,<br><br>I'd like to add that you may gain something on MS JIT compiler using <br>for (int i = 0 ; i &lt; x.Length ; i++)<br>instead of<br>for (int i = 0 ; i &lt; len ; i++)<br><br>This may seem counter intuitive, however that's the scenario in which<br>JIT eliminates array bound checking for the x array (however not for the<br>second one) as arrays have constant length. I am not sure whether Mini<br>recognizes that. I'm pretty sure that Hotspot is much smarter here ;)<br><br>As Zoltan wrote in the bug comments, enabling LLVM improves the results<br>a lot. This is, I guess, due to much better register allocation in which<br>domain Mini isn't too good - and probably other optimizations like<br>better loop unrolling.<br><br>If I remember correctly, there once was a branch of LLVM with array<br>bounds check elimination, is it still developed?<br><br>I am also curious which code patterns enable ABC elimination in Mini.<br><br>On Sun, 2011-11-20 at 08:01 -0500, Jonathan Shore wrote:<br><blockquote type="cite">Here is a link to and entry in bugzilla with attached code. &nbsp;I could<br></blockquote><blockquote type="cite">not send to the list:<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><a href="http://bugzilla.xamarin.com/show_bug.cgi?id=2098">http://bugzilla.xamarin.com/show_bug.cgi?id=2098</a><br></blockquote><blockquote type="cite"><br></blockquote><br>--<br>Regards,<br> Konrad<br><br><br></div></blockquote></div><br></body></html>