Can we stop with the erlang/Elixir is slow? For most web services it is as fast as go.
For my last side project I was evaluating go and erlang. Just to test out how faster go is, I quickly coded a simple HTTP request in both language(I am not an expert in either).
The server would get a request with large body, cache it to a file on the disk, then load it in 128k chunks, get the hash of the chunk and save both the digest and the 128k data to a database.
To my surprise, erlang was consistently slightly faster for each request. Happy to share the code snips of both if anyone want to audit/scrutinize.
Your Go code uses "defer" in a for loop, which could be a performance bottleneck. The deferred function call doesn't run until the saveToDb function returns. A simple fix would be to reuse the rows variable and put the defer outside the loop.
I believe it might, depending on the database driver, also cause another issue. Since you're not closing the rows right away, and not even consuming the rows, this may force the driver to mark the internal connection as busy until the defer runs, meaning the next database call would have to open a new connection. Try closing the rows as soon as you can.
If you don't expect any results, you can also use Exec instead. Then there's nothing to close.
I keep the habit of deferring immediately so I don’t forget later if the fucnction gets long. But I see what you mean, on this case, inside the loop, is really bad idea.
Will try with Exec and without the defer and see if it makes a noticeable difference.
The driver is the MySQL one for what’s worth it. Postgres was a bit slower.
We did this experiment too! When we did our initial benchmarks, Go had a healthy performance lead on pure CPU or IO workloads over Elixir and Scala.
Then we went through with the full POC of our toy webserver project and the performance difference between Go, Elixir, and Scala was pretty much insignificant (within 5% of each other).
The difference is that in Go sha256.Sum256() is implemented in Go and I'm pretty sure in Erlang crypto::hash() is implemented in C.
The program is mostly i/o with sha256 being the only CPU intensive part. If sha256 (or any compute-intensive part) was implemented in Erlang, it would be at least 10x slower than Go version.
Go version probably has a bug: file.Read() doesn't guarantee to fill the buffer, you need to use io.ReadFull() for that.
Both versions unnecessarily write a copy of the file to disk (and don't seem to delete those randomly-named files from disk).
In Go saveToDb() would take io.Reader as an argument and you would pass r.Body directly.
Go is much faster than Erlang, it just doesn't show up in every toy program.
Just to update that getting rid of the part of saving to the disk first, and getting rid of the defer as another person suggested, the number now are around 200ms for golang and 210 for erlang.
IMHO it is not as huge as everybody makes it look like.
Again, as you very correctly pointed out, this is of course only for IO intensive applications.
Did you miss the: “For most web services it is as fast as go.”?
I think the request in my test is quite representative of what an actual web server will be like: mostly IO.
As a general programming language, go is much faster, I completely agree with you.
Btw: I don’t think deleting the files would make a difference. Also I save the body to file first because with cowboy I had trouble splitting it to the exact chick sizes. Will try without it in go and update.
Elixir is slow enough to get in the way, if we're talking about complex processing tasks. I (along with a team) was tasked with writing a fairly complex accounting/numerics application in Elixir, and one day I had to basically call the whole thing a thousand times more often per request. It took me weeks to accumulate enough microoptimizations to make the thing function (because it was already reasonably well designed).
It's a sort of a "it's fast enough until it isn't" type thing. Python is fast in the same way (and faster with each release!).
For anything that isn't dominated by network and database time, language and runtime performance matters, and OTP/Elixir is slow in that way. In terms of "real world performance", it can sometimes matter more that the incremental cost of preempting your beam process is low, more than whether your process completes in more or less time.
Exactly, even fairly complex script languages manages to boot, execute and exit in just a few milliseconds.
Maybe jigsaw is one piece in the puzzle to reduce the time it takes to start.
I doubt it's so bloody complicated, except AOT compilation of all system jars, I suspect it's mainly a matter of getting the time and resources to look at what happens when hello.world is executed.nu
That and relabling executable jars to jxe and the desktop is Java's to grab (that last part was a joke)
For my last side project I was evaluating go and erlang. Just to test out how faster go is, I quickly coded a simple HTTP request in both language(I am not an expert in either).
The server would get a request with large body, cache it to a file on the disk, then load it in 128k chunks, get the hash of the chunk and save both the digest and the 128k data to a database.
To my surprise, erlang was consistently slightly faster for each request. Happy to share the code snips of both if anyone want to audit/scrutinize.
Edit: Code for both: https://pastebin.com/aBQWqkG3
On my laptop a single request(1.2MB) takes around 230ms for Erlang and 280ms for Go. Not a scientific test, but it gives an idea.