Live data from Hacker News

Optimising for Concurrency: Comparing the BEAM and JVM virtual machines

erlang-solutions.com

71–80 of 114 posts

Re: Optimising for Concurrency: Comparing the BEAM and JVM virtual machines

#71

the author leaves out Kotlin which adds support for coroutines on the language level and still compiles to java bytecode. These are not classic continuations because they cannot be cancelled, but they're still very useful and true fibers. There's also the Quasar library that adds fiber support to existing Java projects, but its mostly unmaintained since the maintainers were pulled in to work on Project Loom. Then the…

Fair point - all this is true.

As a counter-point, I've been working on a platform for the last few years which uses Kotlin and Quasar in production. Quasar was cool at first but now it's just a nightmare and I wish we never opted to use it. It leaks abstractions all over the place with @Suspendable annotations and users of the platform find the quasar related errors super confusing. Debugging is also very difficult because of Quasar. On the other hand, Kotlin is great!

If I could turn back the time, I'd build the messaging/async workflow part of the platform using Erlang. I've mentioned this to a few people but they all think I'm mad... "Erlang... are you on drugs?!", which is disappointing because it's literally perfect for our use case.

Re: Optimising for Concurrency: Comparing the BEAM and JVM virtual machines

#72

the author leaves out Kotlin which adds support for coroutines on the language level and still compiles to java bytecode. These are not classic continuations because they cannot be cancelled, but they're still very useful and true fibers. There's also the Quasar library that adds fiber support to existing Java projects, but its mostly unmaintained since the maintainers were pulled in to work on Project Loom. Then the…

Is Java the best out there?

[deleted]

Re: Optimising for Concurrency: Comparing the BEAM and JVM virtual machines

#74

the author leaves out Kotlin which adds support for coroutines on the language level and still compiles to java bytecode. These are not classic continuations because they cannot be cancelled, but they're still very useful and true fibers. There's also the Quasar library that adds fiber support to existing Java projects, but its mostly unmaintained since the maintainers were pulled in to work on Project Loom. Then the…

Don't forget ZIO (and other Cats Effect based libraries) which is the new kid on the block, and has it's own take on fibers and concurrent programming.

The biggest problem with Erlang is that hardly anything out there needs this level of concurrency and robustness in a single system - in the new world of microservices and serverless architectures there are other ways to cope with scaling. This is the main selling point, and unfortunately in all other areas Erlang is significantly outdated and refuses to evolve - even less so than the Java language which is a dinosaur in itself.

Having said that I think Erlang is a fantastic teaching tool and should be on everyone's bucket list of "things to learn in this life as a software engineer".

Re: Optimising for Concurrency: Comparing the BEAM and JVM virtual machines

#75
post #65
post #50

Earlier quoted context omitted.

... what are they?

https://docs.oracle.com/javase/8/docs/api/java/util/concurre... And given that you didn't know that, you really need to study them. java.util.concurrent is one of the greatest gems of software ever written.

So I describe the shortcomings of CompletableFutures, and you point out that there's a java.util.concurrent package?

Is this method one of its gems? A cancel() which doesn't cancel? https://docs.oracle.com/javase/8/docs/api/java/util/concurre...

> Synchronized primitives don't compose. You can safely `synchronized get(...)` and safely `synchronized put(...)`. But their composition put(get(...)+1) isn't synchronized.

So is there anything in java.util.concurrent that does compose? put(get()) has exactly the same problem up here at the 'high level' (of CountdownLatches and Semaphores) as it does at the 'low level' (of synchronized methods.)

Re: Optimising for Concurrency: Comparing the BEAM and JVM virtual machines

#76
post #68

Earlier quoted context omitted.

Java's GC has to be best in class because of shared memory. In a shared nothing world doing GC in one "thread" doesn't stop other threads from executing, it also means that each heap can be very small so you might not even need to perform gc before the thread is done executing. It's truly amazing what Java is doing, but keep in mind that Erlang has worked this way for _decades_. And still, a classic web server that s…

Per thread GC is definitely a different approach than Java takes. The trade-off is that shared memory between Java threads is nearly free. Basically the same approach C++ uses, except Java has better concurrency primitives because its VM. Not sure about Erlang but data sharing between processes on JS and Python is very expensive and a frequent criticism of those languages. You can achieve zero garbage per request in…

In Erlang processes need to send messages to each other. And those messages are copies (nothing is shared). This is less efficient than in Java where everything is shared, but it also means that process a cannot change something that process b is looking at. So locks in Erlang, aren't necessary. It also enables easy distribution. When all processes share data by messaging, it doesn't matter if those processes are running on the same machine or are distributed on a network.

Since Erlang has one GC per process, you can create garbage in one process without triggering GC if that process is short lived. Once the process dies, the entire heap for that process is returned to memory. So in Java, you'd have to write code in a special way to avoid GC, but in Erlang that happens automatically if either your process exits before the heap for that process needs GC. And in Erlang it's pretty normal to run one process per http request, so this does happen in practice, without requiring anything of the programmer.

When it comes to hot code reloading and data migration. When you hot load code into an Erlang vm, a hook will be called if defined which allows you to migrate all data that is in memory into new format. So, you're not restricted by data-incompatibility.

Your last paragraph is what I referred to by required discipline. Everyone that touches the code is required to understand what causes corruption and what doesn't. It also requires that you know which classes are thread safe and which arent, which is hopefully documented somewhere. Thread groups need to be understood (I work in Java/Kotlin every day, and I didn't know what thread groups were before today). In Erlang, data corruption due to multiple processes doesn't happen, and grouping processes together (supervision trees) is so common I can't remember the last time I saw an Erlang program without one.

Which of course doesn't mean that Erlang is superior to Java. But when you're working on something highly concurrent which needs to be fault tolerant, I'd argue that you'd get a better result with less effort than in Java. But of course, if you know Java really well and don't know Erlang at all, YMMW.

Re: Optimising for Concurrency: Comparing the BEAM and JVM virtual machines

#77
post #74

the author leaves out Kotlin which adds support for coroutines on the language level and still compiles to java bytecode. These are not classic continuations because they cannot be cancelled, but they're still very useful and true fibers. There's also the Quasar library that adds fiber support to existing Java projects, but its mostly unmaintained since the maintainers were pulled in to work on Project Loom. Then the…

Don't forget ZIO (and other Cats Effect based libraries) which is the new kid on the block, and has it's own take on fibers and concurrent programming. The biggest problem with Erlang is that hardly anything out there needs this level of concurrency and robustness in a single system - in the new world of microservices and serverless architectures there are other ways to cope with scaling. This is the main selling poi…

Yes, that's a problem, you can't be the only one responsible for a core part of the stack.

I did an interview at a major streaming company and one critical part was written in Erlang. It has been working great but the guy who wrote it had left for some time and nobody knew Erlang there, so they would have to rewrite it if an update was needed.

Re: Optimising for Concurrency: Comparing the BEAM and JVM virtual machines

#78

> Programming with concurrency primitives is a difficult task because of the challenges created by its shared memory model. I never understood this often repeated point. As junior / mid-level developer I had the privilege to run self written .jar files on government scale systems with more than 50 cores. I used Java thread pools and concurrent data structures to do heavy cross thread caching. It was all pretty simple…

I started to write a response but remembered rich hickey talk I went to where he lays out problems with java style concurrency Clojure Concurrency - Rich Hickey https://www.youtube.com/watch?v=dGVqrGmwOAw Even though the talk is called clojure concurrency, first half of the talk is about the problems clojure solving in traditional concurrency. one my favorite talks I ever went to.

What are his thoughts on Erlang? (I have not finished the talk video yet.)

Re: Optimising for Concurrency: Comparing the BEAM and JVM virtual machines

#80
post #75
post #65

Earlier quoted context omitted.

https://docs.oracle.com/javase/8/docs/api/java/util/concurre... And given that you didn't know that, you really need to study them. java.util.concurrent is one of the greatest gems of software ever written.

So I describe the shortcomings of CompletableFutures, and you point out that there's a java.util.concurrent package? Is this method one of its gems? A cancel() which doesn't cancel? https://docs.oracle.com/javase/8/docs/api/java/util/concurre... > Synchronized primitives don't compose. You can safely `synchronized get(...)` and safely `synchronized put(...)`. But their composition put(get(...)+1) isn't synchronized.…

What do you mean the cancel method doesn't cancel ? It does cancel with a CancellationException stored in the future and an optional interrupt send to the thread running the blocking operation.
Post reply on HN