If performance, efficient output, and functional programming in the browser 
is what you are looking for OCaml + Bucklescript or ReasonML+ Bucklescript 
would be a solid fit! They guys behind these projects are great and 
helpful! https://discordapp.com/invite/reasonml

On Monday, December 26, 2016 at 12:44:49 PM UTC-5, GordonBGood wrote:
>
> *Synopsis:*  Some, including  Evan, maintain that Elm can be "faster than 
> JavaScipt".  While that may be true for some use cases including use of 
> perhaps more efficient UI updates due to compartmentalized use of 
> VirtualDOM, the actaul Javascript code generated by the compiler  is not 
> very efficient for many/most tight code cases.  The reason is often 
> unnecessary nested function calls that could easily be eliminated by making 
> full use of the type information that the Elm compiler has.
>
> Part I
>
> *An example;*  The following tight loop doesn't really do anything, so 
> should therefore compile into the very tightest of code (and I'm not 
> expecting the Elm compiler to recognize that the result is actually known 
> at compile time):
>
> range : Int
> range = 1000000000
>
> testProg : Int -> Int
> testProg n = -- do some work
>   let lmt = min (n + 100000000) range in
>   let loop i =
>     if i >= lmt then i else
>     loop (i + 1) in loop n
>
> which compiles to the following JavaScript:
>
> var _user$project$Temp1482759649866537$range = 1000000000;
> var _user$project$Temp1482759649866537$testProg = function (n) {
> var lmt = A2(_elm_lang$core$Basics$min, n + 10000000000, 
> _user$project$Temp1482759649866537$range);
> var loop = function (i) {
> loop:
> while (true) {
> if (_elm_lang$core$Native_Utils.cmp(i, lmt) > -1) {
> return i;
> } else {
> var _v0 = i + 1;
> i = _v0;
> continue loop;
> }
> }
> };
> return loop(n);
> };
> All right, the code looks fairly good, and we can see that for the inner 
> `loop` function that the compiler used its new capability to do tail call 
> optimization and turn it into a while loop.  Also, one might expect that 
> any decent JIT compiler such as Chrome V8 will use constant folding and get 
> rigd of the `_v0 variable.  However, the real limitation of this loop is 
> the call to the `Native_Utils.cmp` function.  Function calls are expensive 
> at 10's of CPU clock cycles each!
>
> The pertinent JavaScript for `Native_Utils.cmp` is as follows:
>
> var LT = -1, EQ = 0, GT = 1;
>
> function cmp(x, y)
> {
> if (typeof x !== 'object')
> {
> return x === y ? EQ : x < y ? LT : GT;
> }
> ...
>
> Note that there are three native branches here (in addition to the 
> enclosing one):  one for the check to see it the arguments are objects 
> (which of course they are not in the case of Int's as here or Float's as 
> the compiler well knows), one to check if they are equal. and (given that 
> generally they won't be equal most of the time) one to see which is 
> greater.  Now these conditions are not so bad by themselves as they are 
> very predictable for modern CPU's branch prediction (i is almost always < 
> lmt), so that will cost at most a few CPU cycles; However, the call to the 
> function in the first place will cost 10's of CPU clock cycles!
>
> Given that the compiler already knows and strictly enforces that the 
> arguments are both Int's or Float's (which are both just Numbers in 
> JavaScript), there is no reason that it cannot directly output (i >= lmt) 
> instead of the function call and make the whole inner loop take only a few 
> CPU clock cycles (on a JavaScript engine such as Chrome V8).  If the 
> compiler were consistent in applying this specialization rule, there would 
> be no need for the `Native_Utils.cmp` function to do the check if the 
> arguments are objects, but for safety's sake and considering that one extra 
> check in the case of objects is likely negligible compare to the object 
> processing, it may as well be left in for its true best use case of 
> comparing objects of the various kinds.
>
> *The Elm Compiler only deals with two primitive types:  Int and Float 
> (which are both actual Number/Float to JavaScript), which makes direct use 
> of primitive operands very easy*
>
> *Part II*
>
> In a similar way, the definition of the Bitwise library to emulate 
> Haskell's definition of the Data.Bits library was silly for only five Int 
> functions, made even worse by a name collision with the Bool `xor` 
> operator.  Because these are library functions, there is at least one level 
> of function call for every use.
>
> *Just as for the above function call for known primitive types (in this 
> case only for Int), these functions should be added to the Basics library 
> as operators with appropriate infix levels and with the names `&&&`, `|||`, 
> `^^^` , `<<<`, and `>>>` just as for F# (which Elm emulates more and more), 
> with the Elm compiler directly substituting the equivalent primitive 
> JavaScript operators.  The Bitwise library, which should never have 
> existed, should be canned.*
>
> Note that although this will make bitwise operators much faster than 
> currently, programmers should be aware that there are many operations 
> taking place under the covers that may not make these operations as 
> efficient as possible alternate means:  under the covers the arguments are 
> and'ed to produce 32-bit values, the operation is carried out, and then the 
> result is sign extended to convert back to a Number/Float, although for a 
> sequence of bitwise operations, the JavaScript engines may only do the 
> conversions at the beginning and the end of the sequence.  Also, using bits 
> in place of Bools does save space but doesn't save as much as perhaps 
> thought:  32 bits are stored in a 64-bit Float, which may not save much 
> space as compared to Bool's, especially as some JavaScript engines by 
> automatically do the specialization.  In other words, potential time and 
> space savings must be tested.  But in any case,these operations may as well 
> be as efficient as possible and this above changes should be made.
>

-- 
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 [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to