6 ms·
Erlang is not as peformant as Java, but there are plenty of reasons to prefer the former to the latter: - a much better concurrency model, that gets you parall
by lliamander 4y ago
Erlang is not as peformant as Java, but there are plenty of reasons to prefer the former to the latter:
- a much better concurrency model, that gets you parallelism for free just by adding cores
- no global gc pauses, low-latency
- fantastic operational tools (trace debugging, remote shell, etc.)
- Erlang/OTP gives you great middleware out of the box, including including queues, pub-sub, service monitoring, database, etc.
- Honestly just a more expressive core language.
All that said, I don't really have anything against Java. It is a great language for the server, but it is not the only choice.
- haspok 4y agoAll that said, Erlang is a very sharp knife, built for one specific purpose. This is just not true: "a much better concurrency model" If your program is CPU-bound, where real threads are king, then Erlang is a pretty poor solution. Because you cannot have real threads in Erlang, even if you wanted to. Number crunching or string processing are not its forte. Also, most enterprise software does not really benefit from green threads anyway, because the scale they are running on easily handles blocking JDBC and http request calls. Not all companies are google or want to run a telephone switch that handles >million concurrent calls... And finally, if you go Erlang, you get actors, whether you like them or not. You cannot have CSPs, for example, which in many ways are superior to actors. You don't get to choose your concurrency model, it is chosen for you. If your use-case suits this model, great. If not... not so much.
- lliamander 4y agoThere are responses to each of those points, but ultimately you are right that there are tradeoffs. My point was really that Java isn't the only sane server-side language, and that Erlang is an entirely sane option. The one thing I will say is that, when I say Erlang has a better concurrency model, I mean that it is much easier to write correct concurrent code in Erlang than in Java.
- andrekandre 4y ago> CSPs, for example, which in many ways are superior to actors how is csp superior to actors?
- neeleshs 4y agoBiggest benefit with Erlang for me is preemptive scheduling. Has a perf hit, but you don't get brownouts. Java lacks this and this results in hanging threads. A lot monitoring has to be there to detect these conditions . Project loom makes this somewhat better, but at its core, java threads are not preemptible
- imtringued 4y agoJava uses regular OS threads that provide preemption by default... Whatever you are talking about has nothing to do with preemption.
- neeleshs 4y agoRight. I meant interruption is cooperative. https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html https://docs.oracle.com/javase/tutorial/essential/concurrenc...
- the8472 4y ago> - no global gc pauses, low-latency ZGC has sub-millisecond pauses https://malloc.se/blog/zgc-jdk16 https://malloc.se/blog/zgc-jdk16 And afaik azul's C4 collector has no global pauses, only per-thread pauses (which are also short)
- pkolaczk 4y agoLow pauses, low memory overhead, low CPU overhead. In Java world, pick one. In C/C++/Rust/Zig you can have all three at once.
- krzyk 4y agoAdd memory safety to the list. And allow to select only 3.
- pkolaczk 4y agoBut that's not performance category. And, btw, Rust has all 4 of them. If we're talking about safety guarantees then let's add data race freedom to the mix. Or use-after-free protection for non-memory resources. ;) Java is cool language and has many nice features, but its type system is not its major advantage.
- kaba0 4y agoMalloc and friends have much more CPU overhead than a modern GC, so if you do choose all of these, brace yourself to a really micromanaged programming.
- pkolaczk 4y agoThat's a common wisdom, but there is little if any evidence to support it. True GC costs are simply more hidden and harder to measure. A malloc/free pair might be slightly slower than Java's new (not by much really - go measure), but invoking `new` is not the only cost of GC. https://arxiv.org/abs/2112.07880 https://arxiv.org/abs/2112.07880 Also modern low pause GCs have way higher CPU overhead than the old STW ones. Try to set a low pause GC pause target to 0.1 ms or set the heap limit to 110% of live memory and see what happens to CPU consumption. Last time I tried, the app didn't even start - got OOM nearly instantly. There is a reason the study above measures at 3x oversized heap. The cost of GC is lower than malloc/free only if you give it a lot more memory than you actually need. Which in many cases is a good tradeoff to make, but it is good to know such tradeoff between memory and CPU exists. And finally there is one more thing that's not particularly a trait of GC, but rather a limitation of current Java - it is much easier to write a C++/Rust program with low number of heap allocations than in Java. The fact that malloc is slightly slower does not matter if you invoked it 10x less frequently.
- bullen 4y agoNo Erlang can't share memory between cores atomically. Erlang can only scale 1-to-1 things like phone calls. Java is the ONLY language that scales many-to-many with stable non-blocking IO and concurrent parallelism that shares memory atomically AND doesn't crash.
- TheRealDunkirk 4y agoAnd for the fraction of the software projects out there that that actually need this feature as a hard requirement, I'm sure it's wonderful.
- pdimitar 4y agoYeah, all web apps everywhere are definitely a fraction, I'm sure. :P Green threads are an amazing fit for web apps. I made a career out of using those for web apps and API apps.
- TheRealDunkirk 4y agoI've been writing (primarily) web applications for the past 25 years or so, with PHP, .NET, and Ruby. "Scaling many-to-many with stable non-blocking IO and concurrent parallelism that shares memory atomically AND doesn't crash" has never once been an issue that has come up in all of that time.
- pdimitar 4y agoOne anecdote does not cancel another. My response would be: consider yourself lucky. It was an issue in my career, many times.
- bullen 4y agoWell many-to-many IS the point of the internet. Think MMO here, which is the "metaverse" thing they keep talking about. Simulating 3D reality over the network IS the ONLY thing humans can do now that doesn't HAVE to burn all the energy we got left while giving use a tool to experiment without risk. So I'm building the final 3D action MMO game engine.
- bjourne 4y agoImo Erlang's scalability benefits are oversold. Unless you're a national carrier the performance of Java far outweighs Erlang's scalability. Instead, Erlang's undersold killer feature is its robust support for hot code reloading. It enables almost any part of the system to be upgraded without affecting running processes. Other languages and VMs can't do that because they optimize call frames differently and rely on mutable state. It's like building a new road on top of an existing one without impacting traffic. Almost magic and very important for always on services like emergency numbers.
- lliamander 4y agoYep, I would say that it's support for ops in general is it's biggest strength (deploys, monitoring, fault tolerance, etc.)
- kelnos 4y agoI feel like Erlang somewhat missed its timing window on this, though. With platforms like AWS, GCP, and Azure, you don't really worry about upgrade downtimes, because you just roll out a new fleet of servers (or new fleet of pods, if you're using something like Kubernetes), and then drain the traffic from and decommission the old fleet. Certainly there are a lot of companies managing real physical servers, where this is not as feasible, but I think the ease of server provisioning makes hot code reloading just not that important to most engineering teams. (And personally I'd be wary of using something like that, considering that the rollback path -- in that case that you deploy bad code and need to back it out -- sounds not as robust.)
- lliamander 4y agoI work in an AWS/K8s-heavy shop, and it is pretty great, but we have a fairly sizeable engineering team. Managing K8s microservices is easily an order of magnitude more work than managing them in Erlang as applications.
- chii 4y agoonly works if your application consists of stateless requests (like http traffic). If your application require a persistent connection (e.g., you're a real time streaming service, or video), you will have to write some application specific code to migrate the current state over to the new cluster being provisioned. This is actually quite hard to get completely right, and quite application specific (i mean, a very simple method would be to store some sort of identifying token, and when the new connection re-establishes, you reload the state back from when the disconnection happens). Erlang lets you do this for "free".
- exabrial 4y ago> no global gc pauses, low-latency Java also has this for at least a few years now. G1GC and ZGC in JDK17 offer no global stops unless absolutely necessary, and ZGC even has latency targets.
- MaxBarraclough 4y agoAlso Shenandoah. Those Java garbage-collection folks have been busy recently. Or is it that people interested in doing ground-breaking garbage collection research tend to target Java?
- origin_path 4y agoNot quite. G1 offers pause time goals so you can balance throughput or latency but it still has global pauses. ZGC doesn't because it doesn't pause your app. Its design doesn't allow any tradeoffs there.