Over last days, I’ve considered many options to add Python, PHP and Rhai scripting support to my webserver project. Several alternatives to approach a solution for this came up at first, the #1 is over static linking, but I want this worker to be and much reusable as possible across several hosts which has scripting enabled.
Right now I’m considering a separate process for this worker, and IPC as communication method, I know there’s iceoryx2, ipc-channel and ipmb as IPC options, but anyone ever had a chance to benchmark any of them?
I do not have benchmarks, but we're using gRPC (tonic on top of tokio.)
It is not the fastest thing of the world (gRPC does a lot of copy and some data is redundant due to backward compatibility and everything is async to supports lots of clinets and it runs on top of HTTP2 after all) but it is still much much faster than typical "json-based home-made solution", and completely type-safe (almost completely: some things are Optional there again becase of backward compatibility)
The good part is it has a tooling for every single language, extensive documentation, and it is backed by Google. I'd say for most of the cases it is good enough.
Those langs probably support some of the following:
sockets
named pipes
stdio comms
shared memory
a fast mq
Depends on just how many calls and context switches you want to have across the boundary.
Usually you have a polyglot system because of some particular binding, either to an external system (e.g. it's much easier to talk to AWS in some languages than others simply because bindings are better supported), a specific hardware (CUDA), or operating system component. Most of the time you can minimize the comms. So figure out what sort of communications load you're looking at, and go from there.
Annoyingly this post apparently had a link to exactly the sort of benchmark you're asking for, but the link is dead now:
From a very quick peek it seems like iceoryx2 is so absurdly fast (to the point you need to measure in nanos) there's no reason to look further for performance only if that's your only concern... but like all those crates AFAICT it's only for Rust to Rust IPC. Assuming you're using either a Rust FFI host or "native extension" to get that running within the target language, you're still going to have to cross an FFI boundary on the other side, and depending on the language that can be quite expensive relatively, maybe in the tens to even hundreds of microseconds (if there are forced GC allocations and copies)
You might even be better off performance-wise using a simpler (though probably not JSON!) IPC mechanism that can be more easily directly implemented in the hosted language and skip the Rust bridge, but that's very specific to each language.
Looks like it partially lines up with my expectations that seemingly the overhead of marshalling/calling into a library alone would become a dominating factor at small payload sizes once you're down to those sorts of numbers, but I admit I'm surprised how much more performance there was to scrape out with manual syncing!
I know that iceoryx2 has bindings in other languages (at least C++ and Python) and from the documentation it looks like they also support cross language communication.
Sounds like you're still ending up with FFI, as I was saying, though. The point wasn't that you can't use it cross language, it's that as that sort of performance level you're going to have to take the language binding cost into account too.
C and C++ do not add any measurable latency but they use a threadsafe service variant which itself adds around 20ns-30ns latency on top. Python is a bit slower but this is due to the nature of the language.
Here is a benchmark graph comparing the latency in relation to the payload size: Gnuplot
And here are the benchmark results for iceoryx2 on different machines: Gnuplot