Nice!
Will the call performance continue approaching the QT signal-slot architecture or do you think you are already there?
It's much closer. Google says QT signal/slots are about 10x slower than a C++ virtual method call. Virtual calls are about 2-3x slower than a direct call. Meaning slots are 20-30x slower than a direct call.
That means a Sigils call is probably about 2-3x slower than calling a QT slot. Without actually testing it I can't be sure.
For local calls Sigils should be able to be sped up to match QT. Currently all parameters are packed into a ref object which incurs extra overhead and is not needed for local calls.
Support for local queued calls has been added with connectQueued! It's part of the threading module, but doesn't require a separate. It builds on the event loop and queue used for threading support though.
It's similar to "run soon" in async. Made it really easy to solve a work problem where I wanted a thread to do some work downloading data in batches or when triggered by new work.
I also had GPT-5 write docs for how the threading support works but the result is t the best. Still probably better than nothing.
New Sigils 0.17.1 release. It speeds up calls another 40% or so! That's about 50x slower than a native proc call.
Sigils has been running pretty well in my (limited) production IoT MVPs combined with Mummy. I've tied websocket updates to a signal for updated data. It's working like a charm and all multi-threaded using sqlite3!
There's also support for using CBOR binary serialization which will enabled backends like nimscript and javascript, but I haven't tried it on those yet.
"only 50x slower"? That's massive, why is it so slow?
It is, though in context QT's signals and slots is about 10x slower than a C++ virtual method call. So now Sigils is within 5x of QT's implementation. So it's still "massive" but starting to approach QT's performance.
Similarly Objective-C's objc_msgSend overhead can be "10x-100x on cache miss" compared to a C function. So now it's in the ballpark for the core message passing primitive of iOS/macOS on it's slow path.
The overhead sounds huge, but it's very useable for the target domains already.
The dynamic abilities are worth the extra overhead in the target domains. Not for an inner loop, but being able to do data buses and fans out, etc, would add significant overhead as well.
Sigils intentionally uses a serialization abstraction on arguments to support things like send data in a channel, or queue up a call for later. For non-threaded calls it just uses a variant library, but it still adds overhead.
Profiling it now shows more of a mix of many things remaining:
I worked on something similar over a decade ago in C++: https://github.com/miguelmartin75/wink-signals when I was deep into learning C++ template meta-programming during high school / first year of uni - the library is basically a glorified wrapper for https://www.codeproject.com/articles/Member-Function-Pointers-and-the-Fastest-Possible
Looking back at the code, I'm not sure I trust the benchmark I wrote lol