Hacker News new | ask | show | jobs
by AlchemistCamp 2563 days ago
That's really interesting. How do you use Go with Elixir? I've never really gotten into Go, partially because I feel like there's a lot of overlap with what it does and what Elixir does.

I could see using it for CLIs and various Unix scripting, but I've been doing that with Ruby, for the most part. I also considered learning Go for creating some native binaries for a few critical paths, but Rust seems like the best choice for that. A NIF that crashes is one of the few things that will take down the Erlang VM, so Rust's strong safety guarantees (might) make it worth the steep learning curve.

2 comments

Sorry if I wasn't clear. I don't really combine the two and use whichever makes the most sense. In my day to day, we are primary a Go microservices shop and are exploring Elixir for some video stuff. I've used some Elixir on side projects. Sorry I wasn't clear that I am not combining them, although I imagine if I was going to it would either be over some sort of gRPC implementation or using something like rabbit to hand over tasks.
Ah, that makes sense!
For one Elixir is very slow compare to Go.
Note that I wasn't asking why one would use Go instead of Elixir for a given task. If it's CPU bound, Go would be a better choice.

My question was how the poster was using Go with Elixir. Since they have a big overlap in what they're commonly used for and since NIFs (Natively Invoked Functions) on the BEAM really need to be fail-safe, it's not as clear as how to use these two together as how one would use C in the same stack with Python, for example.

I feel like that article just supports the comment you're replying to. I mean, look at this: https://stressgrid.com/blog/benchmarking_go_vs_node_vs_elixi...

If the article had gone up to 250K connections, Elixir would have fallen down similarly to what happened to Node... although the reasons for Node being unable to keep up were unclear in the article, and I think warranted further investigation that the article didn't do.

For another comparison, feel free to click around on the tabs here: https://www.techempower.com/benchmarks/#section=data-r17&hw=...

The plaintext benchmark is about as far from a computationally intensive task as you can get... it should basically be network-bound, supposedly an ideal task for the BEAM VM, yet the results are clear.

If you turn on additional languages and frameworks, you'll note that Elixir or Erlang are significantly faster than, say, Rails, but Elixir or Erlang are a good 5x to 25x slower than Go.

People have built massive, successful companies on Ruby on Rails, such as GitHub, so don't think that I'm discounting these languages wholesale. You just have to accept that you will be paying substantially higher infrastructure costs if your infrastructure needs begin scaling beyond a single server. If you think that Elixir or Ruby or whatever else is the secret sauce to make your company successful, go for it! But those are a lot slower than Go or Rust or other very fast languages.

Elixir along with OTP and BEAM is sitting at a significantly higher abstraction level than Go. Everything is built around the distributed stateful soft-real time problem domain. While maintaining fault-tolerance.

You can have that in Go as well, you just need to build all the clustering mechanisms, OTP behaviors, tooling, actor model, embedded monitoring services and such from the scratch. You may well see Go significantly slower than Elixir at this point when you finish baking all that into it.

Developer hours are significantly more expensive than hosting. I'd happily pay double for hosting if it meant I could need half the people to accomplish the same task.

You're right about the abstraction but Elixir is slow because the runtime is slower, because of immutability and many other reasons, if you don't use all the message passing features and just do pure CPU computation you will find it's still pretty slow.
> you just need to build all the clustering mechanisms, OTP behaviors, tooling, actor model, embedded monitoring services and such from the scratch

...or just use kubernetes, to cover majority of those features.

I've never used Kubernetes so I don't know what it provides. But I doubt it could provide the mechanisms for two application nodes to connect to each other and automatically share real-time state. Or the monitoring services to the underlying virtual machine's green threads.

Actually which of the above does Kubernetes really provide as it is in the Erlang VM?

that cpu spike in BEAM is actually a runtime setting and doesn't reflect usage; it's intentionally busy-looping the connection accepts to reduce latency.
huh. that seems like a lot of waste for no measurable benefit: https://stressgrid.com/blog/beam_cpu_usage/

maybe it's beneficial to someone, but I don't think that should be the default.

either way, it doesn't change the picture painted by the TechEmpower benchmarks.

In my experience, having clearer cpu metrics is more useful than any hypothetical latency benefits.

However, the hypothetical benefit would also depend on the cpu model; it made a little more sense when they introduced it than it does now. Back then, CPUs took a significant amount of time to change power states, so going to sleep and waking up for an event that comes shortly after could involve quite a bit of delay. Even if the processor didn't fully sleep, it may reduce the clock frequency, and not increase it until you've done a substantial amount of work.

With more recent processors, these delays are much smaller, and perhaps it would have made more sense to control the power states in another way, but there was some justification.

I agree it is a bad default since 10 years