Live data from Hacker News

Programming language comparison by reimplementing the same transit data app

github.com

11–20 of 65 posts

Re: Programming language comparison by reimplementing the same transit data app

#11
post #4

The experience report on Scala I find pretty cathartic. It really is absolutely ridiculous the fetishization of extremely complex FP and type-level hacking that goes on in the ecosystem, to the point where, in the case of the author's hello world web server snippet, it's just so complex and laden with concepts you need to know that are unrelated to the problem you're trying to solve it could be mistaken for a parody…

It's a shame, too, because until that point (when I was still just following the "getting started" docs and doing the first half of the app, which loads a CSV and parses it and stuff), I was actually really enjoying it! The type-magic style of development is so different from what I'm used to, I have periodic crises of conscience where I wonder if I've been doing programming wrong all these years, or if it's an examp…

I dove into the "type driven development" style with Elm (and a little Haskell) a few years back. In my opinion the pure functional style was more important than the type system. Maybe I just didn't try hard enough to think in terms of types, who knows. But I have to admit - not having to worry about run-time errors is quite nice.

Shortly after Elm, I discovered the array languages via J, and felt like I finally found a style of programming that fit my brain properly. Immutable by default, rank-polymorphic, and extremely powerful. Terseness is a feature - when you can write the same program in 1/100 of the code (not an exaggeration), you can explore alternative approaches quickly and find bugs more easily. On the other hand, there's no compiler or fancy type system to find bugs for you, so terseness is also kind of necessary.

Today I'd recommend array language newbies to try BQN or K first. BQN has some features that other array languages surprisingly lack (closures, modules), and only a few idiosyncratic design choices (unlike J which is very weird). K is pragmatic (it has dictionaries and tables!) and is ascii-based, but it has an almost Forth-like minimalism. For someone used to 'import xyz' style programming it's a jarring transition.

Re: Programming language comparison by reimplementing the same transit data app

#12
post #9
post #6

Earlier quoted context omitted.

Are you on OTP 25 ? With the JIT, in theory Jason is faster than Jiffy

Another thing to add, do you log things in the other languages ? If not, what you are probably benchmarking there is how fast your console is in receiving the text (with a lock). Also use a release, it will help some things here, especially on "short" benchmark, and make sure that the JIT is run.

Yep, Elixir 1.14, OTP 25. I set the log level to warn so Phoenix isn't logging anything that I see. Do you think that still impacts performance? I thought Logger compiled out log calls below the level threshold.

Good call on running as a release! I'll try that next.

edit: Ah well, good thoughts but didn't pan out. I updated the logger config to use `compile_time_purge_matching` just to make sure there wouldn't be any logging impact, and I ran the app as a release, but didn't really make any difference in the numbers that I saw.

Re: Programming language comparison by reimplementing the same transit data app

#13

The experience report on Scala I find pretty cathartic. It really is absolutely ridiculous the fetishization of extremely complex FP and type-level hacking that goes on in the ecosystem, to the point where, in the case of the author's hello world web server snippet, it's just so complex and laden with concepts you need to know that are unrelated to the problem you're trying to solve it could be mistaken for a parody…

The Scala 3 requirement really does cripple the choices available. The Scala 3 transition does feel a bit like the Python 3 transition where major libraries and frameworks are really dragging their feet on transitioning because of the high level of effort for very little obvious improvement.

Scala 2 is still getting regular updates so there's no rush to use 3 just yet, I'd recommend picking the framework first and using the Scala version they support. That makes the development experience much better with access to much easier to use frameworks like play or finatra.

Re: Programming language comparison by reimplementing the same transit data app

#15
According to the results, Go and Rust pretty much beat every other language. While Rust is the clear winner, it has a steep learning curve. When it comes to Rust vs Go, I always choose Go, because it still beats all the other languages and at the same time an extremely simple language to learn / read / write. This triplet has a greater weight in my books.

Re: Programming language comparison by reimplementing the same transit data app

#16

The experience report on Scala I find pretty cathartic. It really is absolutely ridiculous the fetishization of extremely complex FP and type-level hacking that goes on in the ecosystem, to the point where, in the case of the author's hello world web server snippet, it's just so complex and laden with concepts you need to know that are unrelated to the problem you're trying to solve it could be mistaken for a parody…

I do wonder where the recommendation to use http4s for beginners came from. http4s is a very capable library (and if you care much about composition it is excellent), but I wouldn't describe the documentation as beginner friendly.

A slightly better starting point for scala 3 + type-safe server building is tapir e.g. https://github.com/softwaremill/tapir/blob/master/examples3/... . With that, you get a declarative definition of your endpoints (+ error types, auth, etc.) that you can use for both servers and clients, which comes very handy when writing integration tests of course.

> absolutely ridiculous the fetishization of extremely complex FP and type-level hacking that goes on in the ecosystem

An alternative way to look at it is that there is a lot of essential domain complexity that gets encoded via the type system to let the compiler do the hard work. That "extremely complex FP" does not arrive out of nowhere - I really recommend at least skimming through the slides from rossabaker, the http4s designer, that motivate where the core type signature comes from https://rossabaker.github.io/boston-http4s/#2

I suppose one of the "features" that I like about the (typelevel) community is that the approach of "worse is better" is not taken, and a lot of effort is expended to make things correct, modular and orthogonal. This has the drawback of increased upfront complexity, that anecdotally pays off the moment your compiler does not error and the program runs as intended.

Re: Programming language comparison by reimplementing the same transit data app

#17
post #3

Oh, hey, didn't expect to see this here. Thanks for submitting! I tried a few days ago but didn't really get any traction.[0] Since I submitted it, though, I posted it to /r/rust and got a lot of feedback. At the time, rust and dotnet were comparable and at the top of the list, with ~10k req/sec. Now rust is far and away the most performant at ~20k req/sec! I also was able to improve Go's performance 30% or so. Still…

Did you post on the elixir forum? Those results seem very low, I feel like there has to be something amiss.

Re: Programming language comparison by reimplementing the same transit data app

#19
post #7
post #3

Oh, hey, didn't expect to see this here. Thanks for submitting! I tried a few days ago but didn't really get any traction.[0] Since I submitted it, though, I posted it to /r/rust and got a lot of feedback. At the time, rust and dotnet were comparable and at the top of the list, with ~10k req/sec. Now rust is far and away the most performant at ~20k req/sec! I also was able to improve Go's performance 30% or so. Still…

> I'm finding I can almost double my requests per second from simply switching the JSON encoder from Jason to Jiffy Personal plug, but have you tried Jsonrs[0]? I typically get much better performance out of it (especially in lean mode, which seems to be the mode you'd want to use for this benchmark) than Jiffy for large JSON encoding workloads. [0] https://hexdocs.pm/jsonrs/readme.html

This is great! Just pushed up a commit that uses it and updated the benchmarks[0]. I'm seeing a 1.6X - 2X improvement in overall performance. Not bad for a drop-in replacement. And since it's based on serde, I trust it, and I feel like trying out a different JSON library is within scope for me of not just "gaming the benchmarks", as this is actually something I'd now consider using at work.

It's not quite as high as I was seeing with `jiffy` (3,800 req/sec here vs 4,000+ with jiffy), but I'm not confident that was a totally fair comparison. `jiffy` doesn't integrate as nicely with Phoenix, so I was just calling `:jiffy.encode(...)` in the controller and then doing a `text(...)` response. I need to double-check if `json(...)` is doing more work here.

[0] https://github.com/losvedir/transit-lang-cmp/commit/140d693b...

Re: Programming language comparison by reimplementing the same transit data app

#20
post #3

Oh, hey, didn't expect to see this here. Thanks for submitting! I tried a few days ago but didn't really get any traction.[0] Since I submitted it, though, I posted it to /r/rust and got a lot of feedback. At the time, rust and dotnet were comparable and at the top of the list, with ~10k req/sec. Now rust is far and away the most performant at ~20k req/sec! I also was able to improve Go's performance 30% or so. Still…

The elixir implementation seems super slow. The first thing that jumps out to me is that we should be using streams instead of just reading the file. The second would be the `schedule_for_route` which should just be a GenServer lookup instead of reading from ets.
Post reply on HN