On Tuesday, 27 December 2016 05:37:43 UTC+7, Robin Heggelund Hansen wrote:
>
> Part I: Evan is already aware of this issue, you can see the full 
> discussion in this github issue: 
> https://github.com/elm-lang/elm-compiler/issues/1528
> The short of it is that the code generator part of the compiler is not 
> aware of type information, and adding this would be a serious undertaking. 
> It will probably come at some point, as there are interesting optimizations 
> that can be made, like the one mentioned
>

Although it is good to see that Even is aware of the issue, it is 
discouraging to learn that the type information is not retained by the code 
generator and therefore this improvement is part of a "huge project"; thus 
the linked issue has been closed.  The person who raised the original issue 
developed some timing results that showed only about a 20% speed 
improvement for the particular code use.  However, when I compare the above 
tight loop written directly in JavaScript, the difference here is about 
700%!  Of course, real use cases won't be quite this large, but I could see 
a fairly tight loop being 300% (+/- 100%) faster.
 

>
> Part II: Bitwise operators are inlined in 0.18, which gave a noticable 
> performance boost in libraries like Skinney/elm-array-exploration and 
> mgold/random-pcg. Having it available as a function (just like +, -, * 
> etc.) allows more flexibility like currying.
>

 I checked and you are right that these functions are now inlined.

The only other thing they should also have is infix for those with two 
operands for better (conventional) clarity of code, but this is no biggy.

It turns out that the huge slowdown as compared to equivalent JavaScript 
code is another instance of the Part I problem as it is caused by a *call 
to `Native_Utils.eq` which is even less efficient than `Native_Utils.**cmp`* 
resulting in about a 1500% slowdown compared to JavaScript for the 
following code:

import Bitwise as Bw

testProg : Int -> Int
testProg n = -- do some work
  let loop i =
    if Bw.and i 0x3FFFFFFF == 0x3FFFFFFF then i else
    loop (i + 1) in loop n

which compiles to:

var _user$project$Temp1482804013226255$testProg = function (n) {
var loop = function (i) {
loop:
while (true) {
if (_elm_lang$core$Native_Utils.eq(i & 1073741823, 1073741823)) {
return i;
} else {
var _v0 = i + 1;
i = _v0;
continue loop;
}
}
};
return loop(n);
};

with  `Native_Utils.eq` defined as:

function eq(x, y)
{
var stack = [];
var isEqual = eqHelp(x, y, 0, stack);
var pair;
while (isEqual && (pair = stack.pop()))
{
isEqual = eqHelp(pair.x, pair.y, 0, stack);
}
return isEqual;
}


function eqHelp(x, y, depth, stack)
{
if (depth > 100)
{
stack.push({ x: x, y: y });
return true;
}

if (x === y)
{
return true;
}
...

For this use case, there are a succession of conditions which won't cost 
that much as explained in the opening post, but it is twice as slow as the 
example in Part I because *there are typically two nested calls of the 
functions `Native_Utils.eq` with `Native_Utils.eqHelp` called from within 
it!*  This is the reason it is twice as slow as the example in Part I.

If and when the issue as of Part I is fixed, then bitwise operations will 
be fixed too.

Meanwhile, for real work programs with intensive bitwise tight loop 
computations, Elm is likely up to about 10 times slower than JavaScript and 
for general numeric tight loop calculations about 5 times slower, which I 
find unacceptable.

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to