On Tuesday, 24 January 2017 18:47:49 UTC+7, Robin Heggelund Hansen wrote:
>
> The reason is that BuckleScript proves that Arrays are faster than 
>> "string" tagged objects and I have tried benchmarking it myself.  In fact, 
>> I have gone further and manually substituted the use of Arrays rather than 
>> the string tagged objects in the generated Elm code to show that is the 
>> reason.  The problem isn't so much the use of Array's versus 
>> objects/records, but the string tags, which as the Elm JS output doesn't 
>> preserve type information except by these tags, are continuously requiring 
>> string processing to determine the type of object at run time.  Elimination 
>> of these strings by using the type information the compiler already has 
>> would greatly speed things even if objects are used, with the further 
>> advantage of Arrays being that their indices are numeric for slightly less 
>> processing (depending on the browser engine used).
>> This becomes readily seen the more functional the code, with the use of 
>> tuples (tagged objects), lots of records (tagged objects), lists (nested 
>> tagged objects) and so on, and these passed as (essentially untyped) 
>> arguments across functions.
>
>
> This goes against my own benchmarks, where replacing current Elm code with 
> arrays proved slower. Accessing an element on a record was faster than on 
> an array. Did you try against more than just one browser?
>

You've obviously been here, done that.  I repeated my tests across Chrome, 
FireFox, and Edge, and found that, as you say, the tagged JS Records were 
generally slightly faster, but the difference was too small to worry about. 
Bigger was the difference in browsers, where the ratio of the fastest 
(Firefox/Chrome) to the slowest (Internet Explorer/Edge) was over two times.
 

> It is possible to eliminate some of the string tags, but in most cases you 
> will need some sort of tagging. ADTs for instance, which is the majority of 
> cases using tags, does pattern matching on the tag because you cannot know 
> at compile time what object you're dealing with. You need some sort of 
> tagging here, and since strings are interned in javascript, equality 
> checking on a string is a very fast operation. In my tests there were no 
> difference between using numbers or strings as tags.
>

If the compiler kept its static type information for the Code Generator, it 
is possible to eliminate all string tags except for the tagged union (it's 
in the name!)/ADT's as BuckleScript does; However, as they don't seem to 
have an execution speed cost, it doesn't really matter for now. 
 

> Records are not tagged. They're just normal js objects.
> Tuple types only uses tags when determining size. And that is only done 
> for comparisons and equality checks if I remember correctly.
> Lists are linked lists, and so require some sort of tagging. The most 
> efficient way would to use some sort of possible null reference instead of 
> a string tag, but I doubt it makes much difference.
>

 Currently Tuple types tags are used to check for the size of the tuple for 
comparisons and equality, but that's just because the compiler didn't keep 
type information and it's too slow on some browsers to find the count of 
fields through a program; the compiler already knew the size of the tuples 
being compared; else it wouldn't have allowed the comparisons in the first 
place in the case of tuples.
Just as for List's, the compiler already knew what type was there and the 
only special case required is "bottom", which could be marked without a tag.
However, as you say the tags don't cost much if anything in execution speed 
and the main cost is only the extra space taken in memory.

If the compiler passed type information to the code generator, Records 
could be added to the comparable super type, functions could be comparable 
(as the compiler knows the type signature), and even tagged unions with 
only one tag could be part of the comparable super group as the compiler 
knows number and type of fields; the only reason they are not comparable 
now is that type information is not passed to the code generator.  The only 
things not comparable would be multi-tagged unions or any kind of stream 
where the compiler does not know the exact type in advance.  In 
BuckleScript, even tagged unions are comparable using the index number of 
the (numeric) tag as the first field.  If all Elm types were comparable, 
there wouldn't be restrictions on what could be used as keys in Dict's and 
Set's and little need for proposed type classes.

Now that I understand how things work better, my main speed issues now are 
the issue that you identified as an issue in eq/cmp calls and library 
things:  the current Lazy library module uses nested functions which can be 
very slow, and it seems to me that there is room for a linear immultable 
array library module like the Data.IArray module in Haskell, which would be 
useful when the current or proposed logarithmic response Array type just 
doesn't cut it.  Lack of these is restricting the ability to do matrix math 
and fancier graphics in pure Elm without JS libraries.

-- 
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