7 ms·
The advantages of Elixir are not performance-related. There is a lot of focus on raw performance on web-related services, when in reality most of their running
by sph 3y ago
The advantages of Elixir are not performance-related.
There is a lot of focus on raw performance on web-related services, when in reality most of their running time is spent waiting for IO. If there are two things the BEAM excels at, is IO and turning almost any problem into half a dozen processes that are scheduled and run in parallel, if not geographically-distributed, with 1/50th the effort of any other language.
We live in a world with 32+ core CPUs. If your load is not spread uniformly all over those cores, you're losing a ton of performance. Handling requests over separate threads, like 99% of languages do, still isn't enough if all the business logic runs on the same thread.
I'm currently writing a web crawler in Elixir, and it is easier to design it so every request is done and processed in parallel, than to write a naive sequential one you'd do in any other language in half a day.
- deleted 3y ago[deleted]
- _m8fo 3y ago[flagged]
- mcintyre1994 3y agoI think Node is still single core by default? Elixir (or rather the Beam) will handle core utilisation so if you start a load of Elixir processes they’ll be spread across multiple cores.
- _m8fo 3y ago[flagged]
- troupo 3y agoIt doesn't effectively do that. It does about 10% of that, ineffectively. Instead of running a single VM with full knowledge of how to run lightweight processes, designed to fully take advantage of modern multi-core CPUs with multiple guarantees enforced by the runtime you have multiple single-threaded VMs awkwardly communicating with each other over a bolted-on API
- di4na 3y agoYeah but then you have to handle a lot of the synchronization of memory. It is hard to make you realise what is possible on the erlang vm without having tried it. In particular, it is preemptive. This... Makes a lot of stuff easier.
- malodyets 3y agoI wish you wouldn’t delete your posts - it makes it hard to understand what the following comments are responding to.
- pdpi 3y ago> I think Node is still single core by default? It’s complicated. Node itself has never been single-threaded. The execution model for JavaScript is single-threaded, so there’s no working around that, but libuv uses threads to build async IO on top of blocking operations. Then there’s worker threads, which are pretty similar to web workers AIUI, that give you parallel execution for cpu-intensive work. Obviously, though, none of these facilities compare with BEAM
- sph 3y agoAsync/await and any module won't save you from global state, data races, and the fact that you're running on an imperative language with mutable state. Additionally, the ergonomics are not the same, so even if you could replicate the BEAM in Node or any other language, you'd have to be a masochist to do it. Lastly, the concurrency are primitives to the entire runtime, not a set of external libraries maintained by whoever, which might be incompatible with other libraries you might want to use.
- deleted 3y ago[deleted]
- tekkk 3y agoNodeJS was designed to run single-threaded. Sure, you can use cluster module to run it with multiple but there's memory overhead and the ergonomics of sharing state and message-passing is nowhere near GenServer. Not to mention all the other benefits of BEAM. But about the specifics of implementing a web-crawler, a NodeJS way to implement it would be to parallelize using lambdas.
- deleted 3y ago[deleted]
- masklinn 3y agoIt’s not even remotely similar. Node’s cluster is just bog-standard OS subprocesses running their own event loop. To spread work over multiple cores with the cluster (or even worker-threads) modules you have to do so explicitely and manually. It’s essentially the same model you get with pthreads, or java, or python. BEAM is a completely different model, the “processes” are internal tasks, which the runtime will schedule appropriately over available cores (the scheduler has been multithreaded for 15 years or so), spawning processes is as common as spawning tasks in JS, except each of these is scheduled on an SMP runtime. beam will literally send processes between machines erlang) more easily than node will balance load over cores.
- deleted 3y ago[deleted]
- imglorp 3y agoAt the Abstractions conference in Pittsburgh in 2016, Joe Armstrong was hanging out in the hallway with his swag bag, just a regular engineer complaining about Jira and his manager (he had no interest in managing) and asking people's opinion about the schedule and lunch places. We were looking at the program for the next sessions and someone said there's a talk about ideas for adding concurrency features to Node, and we said great, lets go, and a few of us went to go stand in the back of that one. On a number of points the presenter was proposing, like message passing, immutable structures, and process tree management, the presenter would say, "but Erlang's had this feature for many years..." and the room would laugh and turn around and acknowledge Joe. He was modest but the validation must have been nice.
- ozr 3y agoI'm unfamiliar with BEAM. How does this compared to goroutines? Obviously they won't migrate between machines, but concurrency feels very easy and ergonomic in Go.
- Volundr 3y agoDisclaimer: I'm not very experienced in Go. Go routines were pretty directly inspired by Erlang processes, so in terms of primitives I'd say they are very similar, aside from go lacking the distributed features you already mentioned. Where Erlang/Elixir add value beyond go routines is what OTP (kind of the standard library) provides on top. Pre-built abstractions like GenServer for long running processes, Genstage for producer/consumer pipelines and supervision trees for making sure your processes haven't crashed and restarting them and their dependents if they have.
- intelVISA 3y agoThose naive sequential services don't really exist in prod though. It would be a dark day to discover my AWS t1.337metal was blocking 63 cores on I/O when nearly every modern lang has a wealth of async functionalities just awaiting to be exploited.
- jeswin 3y ago> ... with 1/50th the effort of any other language. To junior developers reading this, such statements are never true.
- knewter 3y agoThough if people consistently over decades sing a language's praises on a single point consistently like they do the beam on this point, it's usually not without merit
- javanonymous 3y agoThey wrote it from scratch with the benefit of all the knowledge they had gathered after running the old system for years. A 2X improvement would not be surprising to me, even if they had rewritten it in the same language. . According to others in this discussion they also made architecture changes (DB, Kafka etc.). Do we know if that improved the performance? There is no objective way we can tell if Elixir had any performance impact. It could have been due to the rewrite, the architecture change or a combination of both.
- ch4s3 3y agoNot to just toss around anecdotes, but I once rewrote an email service in elixir for a company from a literal sketch on a piece of printer paper describing what their old system did. The new service ran on 1 server vs half a dozen and was both faster at crunching through their mail queue and used far fewer resources. Some tasks are embarrassingly parallelization and the BEAM excels at those tasks. Sure you might want features it doesn't have for certain systems, but for some things it really is the right tool.
- pessimizer 3y agoWhatsapp took over the world running on Erlang/BEAM, with barely any servers and a few engineers. I honestly don't know what could be a better success story than that, but Discord has also done pretty well. The BEAM + Rust combination is looking scarily effective right now.
- mgaunard 3y agoUsing more threads usually makes I/O-bound tasks slower, not faster, unless they're working with different devices or resources. What you need to be fast is a systems engineer.
- Thaxll 3y agoI wrote the same kind of tool in both Elixir and Go, the performance difference was huge between the two, Elixir / Erlang is pretty slow overall.
- zaphar 3y agoThe go runtime has similar capabilities as the BEAM runtime when it comes to concurrent workloads. Go has the benefit of being a typesafe compiled language which gives it speed benefits. But using either one of them instead of Java is probably going to be a huge win for most teams on concurrent workloads.
- throwawaymaths 3y agoDoes it have similar capabilities in fault tolerance?
- cutler 3y ago> But using either one of them instead of Java is probably going to be a huge win for most teams on concurrent workloads Not for long. Something is looming on the horizon in Java-land.
- OkayPhysicist 3y agoSomething's always looming over Java-land: The dark shadow of Oracle, watching over everything with it's flaming eye.
- cutler 3y agoLooming as in Loom-ing.
- panick21_ 3y agoAnd you can achieve better performance with JVM as well. Its just about how you write that Java (or use Clojure) or something.
- 3y ago
- Thaxll 3y agoElixir does not do anything better at IO than other languages.
- zaphar 3y agoThey do have a really compelling conccurent processing story though, which is what most people mean when they say it's better at IO.
- sph 3y agoWhat's "other languages"? IO lists, which are the foundation of anything that build a string incrementally, are managed with vectored IO syscalls out of the box (readv/writev), which you'd have to handle yourself in most other languages, or resort to allocating and endless memory copying which Erlang is able to avoid.
- fluoridation 3y ago>Handling requests over separate threads, like 99% of languages do, still isn't enough if all the business logic runs on the same thread. I mean, if your business logic is inherently serial it makes little difference if you run it in a single thread or if each serial segment in between IO requests is run in a different thread. One way or another it's not going to get parallelized.
- slotrans 3y ago> Handling requests over separate threads, like 99% of languages do, still isn't enough if all the business logic runs on the same thread. When would this EVER be the case? I'm struggling to imagine a scenario where logic doesn't/can't run in the worker thread.
- cpursley 3y agoWhich libraries are you using for the crawler or are you building from scratch? I’d love to hear more about your approach!
- za3faran 3y agoAll of what you mentioned applies equally well, if not better, to the JVM. Especially now that it has virtual threads. The article does not go into details about the implementation of the Java program. My guess is that they were not using asyc code, or profiled it to see what the bottlenecks are. Rewriting is always fun especially in the latest flavor of the day stack.
- kaycey2022 3y agoDoing concurrency in Elixir is only easier once you get your ass kicked doing concurrency in other setups.