On Thursday, 26 January 2017 21:13:33 UTC+7, Bob Zhang wrote: > > Hi Gordon, > I think it is inappropriate to discuss BuckleScript performances on this > mailing list (people may feel unhappy about this), if you are interested, > we can discuss on BuckleScript github issues(I will create a mailing list > too). >
Yes, Hongbo, I considered that, but since the subject of this thread is speed, and BuckleScript has been brought up many times as a speedy alternative to Elm including by yourself as author, I just wanted to show that all is not roses in BuckleScript land. I have done some more work in this issue and am beginning to think that the choice of JS Array's as the base data representation in BuckleScript as opposed to JS Object/Records in Elm/Fable may not have been a good one for consistency of performance across browsers but wonder what you think it is: it seems that Chrome V8 optimizes relative JS Array performance much better than other browsers, especially Firefox, which may be what is reflected here. I also re-ran the functional primes benchmark on Firefox and again found the BS version very slow, in this case about five times slower than Elm. If you want to open up an alternate means of communication about this issue, I will be happy to contribute further as to BuckleScript development. Perhaps an issue should be filed in the BuckleScript repo? Now all is not roses in Elm land either, which IS the subject of this thread: while as Robin Heggelund Hansen has pointed out, JS Objects/Records seem to be a fine efficient data representation across browsers, different browsers seem to do different quality jobs in interning the string tags, or at least Elms way of emitting them, with the Chrome way much more suited than that of FireFox or Edge (the worst) so that I believe that most of the performance issues I have in different browsers are due to this. Of course, if the Elm back end were using the static type information that should be available to it (the actual subject of this thread), this this would not be a problem, as the use of any tag information could be minimized and reduced to identifying which of the set of union cases is in play. What I have learned (and which BS does very well) is that no tags are actually needed or desired except for ADT's/tagged unions (that's why tag is in the name) *if type information is used*, and that while BS uses numeric indices for JS Array's, string/s/symbols with Object/Records are likely at least as good *as long as we help the JS engine do string interning* in order to get better speed consistency across browsers. I will be writing more about this shortly as soon as I complete some more benchmarks. Meanwhile, I now know why elm-lang/lazy is so slow on Chrome V8 when used in lazy lists: they are implemented as nested functions, which sometimes get inlined but when not (as when part of lazy list definitions) are about 50 times slower than Immediately Invoked Function Expressions (IIFE's) on Chrome V8. This is a problem unique to Chrome V8, as new Firefox doesn't have a problem with nested functions at all, and they have a relatively minor cost in Edge. The use of nested functions is a common problem across JS language transpilers (for instance Fable), and although BS has a different implementation of Lazy that doesn't use nested functions, it is the cause of the huge slowdown I pointed out earlier for embedded closures, for which BS does use nested functions. Here is a link to some performance tests and data. <http://jsperf.com/iifes-vs-nested-functions/4> I plan to re-write elm-lang/lazy to use IIFE's instead of nested functions, which should take care of the Elm speed discrepancy problem in Chrome. While this is easily fixed for elm-lang/lazy because it is a library, it isn't so easy to fix for closures that are implemented as nested functions by the compiler itself; although they, too, can be "lifted" and implemented as IIFE's, this needs to be done by the compiler and not just a library. > A minor comment: > > As Elm does not have mutable linear arrays, for the big_uint functions > I created a Native JS based library into which I just inserted the same JS > code as created by the BS compiler for fairness; other than that it uses > the same algorithm as the BS code. > > This is seriously biased, it is similar to when benchmarking the perf of > Python against JS, Python users rewrite the hot function in C and call it > from Python due to the incapability of Python. > While I agree that using a compiled library function in interpreted Python to benchmark Python speed is a fallacy, both Elm and BS are compiled languages with the primary difference that Elm strictly enforces immutability of all data structures at the language level whereas OCaml/BS does not. Now, I could have fairly easily used the current Elm Array type to implement the big_uint type and operators and it wouldn't have been that slow since this benchmark doesn't exceed the current Array linear sub-array size of 32 32-bit Int's (308 decimal digits), but what I really wanted to test was the lazy list function capabilities as to speed and not the overall current language limitations; thus, the shortcut to compare lazy lists like-with-like. Again, the limitations of the current Elm Array can be overcome by providing a linear immutable IArray library module similar to the immutable IArray library module in Haskell without breaking the mandated external immutability of all data structures in Elm, and if that were available then the big_uint functions/operators could be written to be about the same speed as with BS; I am working on such a library module. As I am sure you know, immutability is a blessing as to producing safe reliable code, but it can have a cost in performance as compared to using mutable data structures, which cost can be reduced by careful attention to how immutability is used. All immutable structures go through a mutable stage while being constructed, and I am proposing to make type safe capabilities available to tap into while construction is going on, just as is done in Haskell. By doing that, one can get close to mutable code speed but still using externally immutable IArray data structures, with the limitation that any algorithm taking advantage of this must batch array `set` operations so as to occur during (each) construction; individual `set' calls will be extremely slow and worse than using the Array tree structure of the current and proposed Array library modules. -- 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.
