Hacker News new | ask | show | jobs
by poulpi 2905 days ago
Have you think about including Golang based Lambda function in your benchmark?

As you're guessing that Cloudfare superior JS runtime plays a big role, it could be interesting to see if it can compete against Golang Lambda as well.

2 comments

A lot of our performance benefit comes from lighter-weight sandboxing using V8 instead of containers, which makes it feasible for us to run Workers across more machines and more locations. It wouldn't surprise me too much if a Worker written in JS can out-perform a Lambda written in Go, as long as the logic is fairly simple. But I agree we should actually run some tests and put up numbers... :)

On another note, currently we only support JavaScript, but we're putting the finishing touches on WebAssembly support, which would let you run Go on Workers... stay tuned.

Just curious: The article mentions V8 isolates. Do you actually also run all IO of the worker in the same isolate? Or in a different one, and the API calls are bridged (via some webworker-like API)?

I guess one of the main challenges is that all resources are properly released when a worker is shut down. Releasing memory sounds pretty easy, if V8 does it for you. But releasing all IO resources might be a bit harder, especially if they are shared between isolates.

The Workers runtime itself is implemented in (modern) C++, not JavaScript. So, there's no need for a separate isolate -- API objects are implemented directly in C++.

In C++, memory and I/O resources are both managed through RAII. Of course, when binding to JavaScript, we often end up at the mercy of the JavaScript GC to let us know when an object is no longer reachable from JS, and the GC makes no promises as to how promptly it will notice this (maybe never). That's fine for memory (it amortizes out) but not for I/O resources. So we're back at the original problem.

Luckily, in the CF Workers environment, it turns out that all I/O objects are request-scoped. So, once a request/response completes, we can proactively release all I/O object handles bound into JS during that request/response. If JS is still holding on to those handles and calls them later, it gets an exception.

Thanks for the explanation!

Yes, I guess a part of my question was whether the destructors/finalizers that the JS object bindings in C++ might impose are called fast enough to guarantee isolation and prevent resource leakage. Looks like in your case that happens through the request scoping.

I have a test which dives into the crypto performance, which seems to be largely driven by the amount of CPU allocated to the process (both Workers and Lambda is ultimately just calling a C crypto implementation). I'll have a longer post about it shortly, but the summary is a 128MB Lambda is around 8x slower than a Worker in pure CPU.