On Wednesday, 25 January 2017 11:53:56 UTC+7, Bob Zhang wrote:
>
> I have been working on compilers professionally for more than 8 years, I
> did not read your ocaml code, so I am not sure it's performant ocaml code.
> But anyway, I think you already convinced yourself elm suits your need
> better :-)
>
Hi Hongbo, it's not that I am rejecting your work, but we are on an Elm
forum and the object (for me at least) of being here is to contribute to
Elm and learn how to use it better.
Elm currently has this bit of a niggle in performance for my use, so on
your and others recommendation I have converted to using BuckleScript to
produce Native libraries for Elm, which it does quite well and I'm sure
will do even better in the short term future with your continuing
contributions to BuckleScript development. In fact, with some few extra
improvements in BuckleScript, it doesn't need much in the way of direct
calls to JavaScript, and when required JS calls are extremely easy.
However, if one is to embrace the Elm concept, the goal is to not use
Native libraries at all other than for libraries where it isn't possible
otherwise, and it seems Evan discourages even these unless they provide
some major enhancement to the language environment's capability.
If one were to reject Elm's capability and ecosystem, then BuckleScript
seems to be the most capable alternate programming environment to output JS
and one would likely convert all of their projects to it including using
some sort of Elmish library for implementing the front end client
interaction code. It seems that is what OvermindDL1 has done, at least in
the interim.
As there are a few things about OCaml that I don't care for, especially the
syntax, I am not ready to do that and having narrowed the areas where
performance needs work, will do some more work in those areas to see how
far I can push it before I turn away from Elm likely to pure BuckleScript.
There is no guarantee that "Evan knows best" as to solving what I see as
problems or will solve the issues in a timely manner, I which case I of
course would re-evaluate.
Choosing to continue to work with Elm has nothing to do with the quality of
your work on BuckleScript, which seems to be of the highest standards so I
don't see how it is in any way unfair to your work; in fact, one wonders
why you would consider it unfair, as here you are in the Elm discussion
forum. Surely you are not here to evangelize Elm users away to
BuckleScript?
I did not provide either the Elm code or the BuckleScript code I was
comparing it against for the pure functional primes benchmark as no one
seemed too interested. Both are almost identical other than for
differences in syntax with the Elm code as follows:
module PrimesTreeFolding exposing (CIS(..), primes, countPrimesTo)
type CIS a = CIS a (() -> CIS a)
merge : CIS Int -> CIS Int -> CIS Int
merge ((CIS xhd xstl) as xs) ((CIS yhd ystl) as ys) =
if xhd == yhd then CIS xhd (\_ -> merge (xstl()) (ystl()))
else if xhd < yhd then CIS xhd (\_ -> merge (xstl()) ys)
else CIS yhd (\_ -> merge xs (ystl()))
pmlts : Int -> CIS Int
pmlts p =
let adv = p + p in
let pmltsi c =
CIS c (\_ -> pmltsi (c + adv)) in pmltsi (p * p)
allmlts : CIS Int -> CIS (CIS Int)
allmlts (CIS p pstl) =
CIS (pmlts p) (\_ -> allmlts (pstl()))
pairs : CIS (CIS Int) -> CIS (CIS Int)
pairs (CIS xs xsstl) =
let (CIS ys ysstl) = xsstl() in
CIS (merge xs ys) (\_ -> pairs (ysstl()))
cmpsts : CIS (CIS Int) -> CIS Int
cmpsts (CIS (CIS c cstl) csstl) =
CIS c (\_ -> merge (cstl()) (cmpsts <| pairs (csstl())))
minusAt : Int -> CIS Int -> CIS Int
minusAt n ((CIS c cstl) as cs) =
if n < c then CIS n (\_ -> minusAt (n + 2) cs)
else minusAt (n + 2) (cstl())
oddprms : () -> CIS Int
oddprms() =
CIS 3 (\_ -> minusAt 5 (cmpsts <| allmlts (oddprms())))
primes : () -> CIS Int
primes() =
CIS 2 (\_ -> oddprms())
countPrimesTo : Int -> Int
countPrimesTo top =
let cntp cnt (CIS p pstl) =
if p > top then cnt
else cntp (cnt + 1) (pstl()) in cntp 0 (primes())
`countPrimeTo 1000000` produces the answer of 78498 in about 0.4 seconds in
Elm and about 0.3 seconds in BuckleScript for my SkLake Intel CPU at 3.6
GHz running in Chrome, with Elm coming down to about 0.33 seconds if I
manually patch the JS code to do direct comparisons instead of calling the
eq/cmp functions as per the changes we are trying to get Even to make
(BuckleScript doesn't need this).
I use a (non-memoizing) Co-Inductive Stream (CIS) instead of a full Lazy
List as the algorithm does not need memoization and to save that overhead.
It is several times faster than using Elm's immutable Arrays in their
current incarnation, although still has performance of O(n log n log log n)
with the extra "log n" term as compared to imperative solutions based on
mutable arrays and has a fairly high constant factor overhead, but I wanted
to compare like with like. So yes, I know of ways to make it run at least
500 times faster as a JS library using imperative/mutable code but am here
comparing the functional capabilities of languages. Interestingly, if
implemented functionally in C++ it is only about twice as fast as this JS,
but is about 20 times as fast with Haskell or even something on the JVM due
to more efficient memory allocation/de-allocation (garbage collection).
I have other similar algorithms for functional benchmarking, but this one
is quite typical. I also have linear immutable array benchmark algorithms,
but those require a different IArray library to produce any reasonable
times, so are more difficult to post.
--
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.