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.

Reply via email to