<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><blockquote type="cite" class="">On Oct 12, 2016, at 2:25 AM, Gerriet M. Denkmann via swift-users &lt;<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a>&gt; wrote:<br class=""><br class="">uint64_t nbrBytes = 4e8;<br class="">uint64_t count = 0;<br class="">for( uint64_t byteIndex = 0; byteIndex &lt; nbrBytes; byteIndex++ )<br class="">{<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>count += byteIndex;<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>if ( ( byteIndex &amp; 0xffffffff ) == 0 ) { count += 1.3; } &nbsp;(AAA)&nbsp;<br class="">};<br class=""><br class="">Takes 260 msec.<br class=""><br class="">Btw.: Without the (AAA) line the whole loop is done in 10 μsec. A really clever compiler!<br class="">And with “count += 1” instead of “count += 1.3” it takes 410 msec. Very strange.&nbsp;<br class="">But this is beside the point here.<br class=""><br class=""><br class="">Now Swift:<br class="">let nbrBytes = 400_000_000<br class="">var count = 0<br class="">for byteIndex in 0 ..&lt; nbrBytes<br class="">{<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>count += byteIndex<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>if ( ( byteIndex &amp; 0xffffffff ) == 0 ) {count += Int(1.3);}<br class="">}<br class=""><br class="">takes 390 msec - about 50 % more.<br class=""><br class="">Release build with default options.<br class=""></blockquote><br class=""><div class="">This is a useless benchmark because the loop does no observable work in either language. The C version, if you look at the generated assembly, in fact optimizes away to nothing:</div><div class=""><br class=""></div><div class="">~/src/s/swift$ clang ~/butt.c -O3 &nbsp;-S -o -<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>.section<span class="Apple-tab-span" style="white-space:pre">        </span>__TEXT,__text,regular,pure_instructions<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>.macosx_version_min 10, 9<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>.globl<span class="Apple-tab-span" style="white-space:pre">        </span>_main<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>.p2align<span class="Apple-tab-span" style="white-space:pre">        </span>4, 0x90<br class="">_main: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;## @main<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>.cfi_startproc<br class="">## BB#0: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;## %entry<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>pushq<span class="Apple-tab-span" style="white-space:pre">        </span>%rbp<br class="">Ltmp0:<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>.cfi_def_cfa_offset 16<br class="">Ltmp1:<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>.cfi_offset %rbp, -16<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>movq<span class="Apple-tab-span" style="white-space:pre">        </span>%rsp, %rbp<br class="">Ltmp2:<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>.cfi_def_cfa_register %rbp<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>xorl<span class="Apple-tab-span" style="white-space:pre">        </span>%eax, %eax<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>popq<span class="Apple-tab-span" style="white-space:pre">        </span>%rbp<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>retq<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>.cfi_endproc<br class=""><br class=""></div><div class="">It looks like LLVM does not recognize the overflow traps Swift emits on arithmetic operations as dead code, so that prevents it from completely eliminating the Swift loop. &nbsp;That's a bug worth fixing in Swift, but unlikely to make a major difference in real, non-dead code. However, if we make the work useful by factoring the loop into a function in both languages, the perf difference is unmeasurable. Try comparing:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div class="">#include &lt;stdint.h&gt;</div></div><div class=""><div class=""><br class=""></div></div><div class=""><div class="">__attribute__((noinline))</div></div><div class=""><div class="">uint64_t getCount(uint64_t nbrBytes) {</div></div><div class=""><div class="">&nbsp; uint64_t count = 0;</div></div><div class=""><div class="">&nbsp; for( uint64_t byteIndex = 0; byteIndex &lt; nbrBytes; byteIndex++ )</div></div><div class=""><div class="">&nbsp; {</div></div><div class=""><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; count += byteIndex;</div></div><div class=""><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ( ( byteIndex &amp; 0xffffffff ) == 0 ) { count += 1.3; }&nbsp;</div></div><div class=""><div class="">&nbsp; };</div></div><div class=""><div class="">&nbsp; return count;</div></div><div class=""><div class="">}</div></div><div class=""><div class=""><br class=""></div></div><div class=""><div class="">int main() {</div></div><div class=""><div class="">&nbsp; uint64_t nbrBytes = 4e8;</div></div><div class=""><div class="">&nbsp; return getCount(nbrBytes);</div></div><div class=""><div class="">}</div></div></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class="">with:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">import Darwin</div><div class=""><br class=""></div><div class="">@inline(never)</div><div class="">func getCount(nbrBytes: Int) -&gt; Int {</div><div class="">&nbsp; var count = 0</div><div class="">&nbsp; for byteIndex in 0 ..&lt; nbrBytes</div><div class="">&nbsp; {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; count += byteIndex</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ( ( byteIndex &amp; 0xffffffff ) == 0 ) {count += Int(1.3);}</div><div class="">&nbsp; }</div><div class="">&nbsp; return count</div><div class="">}</div><div class=""><br class=""></div><div class="">exit(Int32(truncatingBitPattern: getCount(nbrBytes: 400_000_000)))</div></blockquote><div class=""><br class=""></div><div class="">-Joe</div></body></html>