> Efficiency in the BEAM is mainly in service of its primary goal of fault-tolerance. If one process crashes unexpectedly, the others should continue. By the same logic, if one process is CPU-intensive or IO-blocked, the others should keep making progress smoothly. And if processes are good for isolating errors and performance issues, they should be cheap enough that we can run a lot of them at once. Those assumptions are baked into how the BEAM manages processes.
If raw speed is your only goal, the BEAM probably isn't the best choice. If consistent speed and stability matter, it may be.
More on this at https://dockyard.com/blog/2018/07/18/all-for-reliability-ref...
- Go wants to be performant at high concurrency scale
- Erlang/Elixir wants to keep running at high concurrency scales, whatever the issues are in your application code. Performance comes second.
There's no clear cut answer to your question; I guess if you trust yourself to write servers that will hold a large number of connections while doing a lot of processing then Go has an advantage, otherwise you should probably trust the man-centuries behind the BEAM VM and follow the various blog posts/presentations explaining how you can fine-tune your machine to get to super large scales.
I want to state that performance is too generalize here.
BEAM VM also have a goal of low latency which can be consider as performance. I'm not entirely sure if GO is aiming for that or not. I would never do any numerical stuff on BEAM though, it's very slow.
This article is a bit dated but is interesting between Go and Erlang:
https://www.theerlangelist.com/article/reducing_maximum_late...
If it's pure benchmarks, then Go is usually going to come in a little bit ahead.
When you get into comparing language design, underlying architectural decisions, problems solved/created/avoided by those decisions it gets more complex.
I did a big write up for code ship a couple of years ago. Had a solid discussion on HN and the comparison remains fairly accurate.
Both of them give you less flexibility than is necessary to achieve highly efficient use of all threads on a multiprocessor system. For that, you'll need something like a pool of event loops using async/await. This is the system most common in high performance networking in C++, C, and Rust.
Erlang and Go both sacrifice efficiency to improve maintainability and safety by offering a model that allows you to approach concurrency from a more synchronous mindset. Erlang in particular goes beyond Go in that the Actor model is considerably easier to avoid deadlocks and other concurrency bugs in at the expense of a much more opinionated system. Erlang is also less focused on reducing average latency as much as keeping latency predictable at scale.
Long story short, Erlang, Go, and the rest are not apples to apples comparisons, and it takes investment in each language to understand the tradeoffs and use cases for each. You should also view them holistically, as in, what language can my team support, and will the wins from Erlang's message queues outweigh the smaller community, or will Go's mid tier performance be enough to avoid writing on top of the low level libevent and building a custom thread pool or fine tuning Go's scheduler.
The question is if you cannor want to write better concurrent code by rolling it yourself.
Some benchmark about pure CPU computation:
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
Erlang is really slower than Java
Go and Java now:
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
You see the big difference, Go and Java are on part but Go usually takes way less memory than Java.
You can't have everything, message passing / immutability with no performance hit.
Are you juggling lots of messages concurrently and orchestrating across complex topologies of nodes? A BEAM language is going to excel. That's why Whatsapp, Discord, and RabbitMQ use Erlang/Elixir.
Are you trying to go really fast in a straight and simple concurrency scenario? Go/Java/C++/Rust is going to be faster than a BEAM language in those scenarios.
You won't want to implement a complex concurrency run-time in Java whereas Elixir is not a good choice for a 3D game engine.
Still, there's nothing wrong with using both.
EDIT: I believe this is partially due to Go being a lot more CPU efficient overall than Erlang (see below). So for simple servers, Go and Erlang will match performance, but for slightly more complex web servers that need to crunch some data, Go [and Rust] will outperform the Erlang VM. https://stressgrid.com/blog/benchmarking_go_vs_node_vs_elixi...