I guess what I'm saying is, the example feels contrived.
I guess what I'm saying is, the example feels contrived.
A good programmer ought to have read that sentence and instinctively observed that between 100ms and 10ns is a full seven orders of magnitude. For two numbers that at the human level may seem not terribly far away from "zero", there's a lot of space between them.
After doing a bit of tuning I was able to steer the microscope with no visible latency, which means I'm handling user events at ~25FPS or higher and not seeing any high variances. The only problems I have are when the handler that receives a signal takes longer than I have budgeted (IE, more than 1000/25).
The retro gaming community is obsessive about input and display latency and even there anywhere between 5-16ms (16ms being one frame of 240p content) is considered acceptable for even the most hardcore twitch response games.
That’s not saying that other processes aren’t happening faster than that, just that human input and subsequent visual feedback maxes out somewhere between 200-300 times per second and for the vast majority of humans, it is far, far lower.
If you measure the response of individual photoreceptors, it takes 25-50 ms to peak after a flash of appropriately-colored light; the precise number depends on the color and intensity of the light. After that, the signal still needs to propagate through a bunch of visual brain areas, and then even more needs to happen to somehow influence behavior. With everything tuned just so, you can complete that whole process in 100 ms or so, but the conditions have to be perfect; otherwise, 300+ ms between (simple) stimulus and (simple) response is more typical.
Obviously, a lot of this is happening asynchronously, and high refresh rates can help in other ways (e.g., by smoothing out movement), but it astonishing how laggy our visual system is.
As for download progress etc.. I don't think I have ever had to worry about speed of a function call ever - as long as I was leaving it to the event loop take care of it.
You wouldn't want to use ObjC's message sending OR Qt's signalling mechanism in a tight inner loop – hell, you probably don't want to deal with the indirection of the vtable incurred by a virtual function in a tight inner loop. But all of these are more than fast enough for interactive UI work.
objc_msgsend is slower than a virtual function, but like 1.1x-2x, not 10x. (In rare cases it can even be faster due to it being a little more predictor-friendly.)
https://www.mikeash.com/pyblog/friday-qa-2016-04-15-performa...
https://www.mikeash.com/pyblog/objc_msgsends-new-prototype.h...
A cached IMP is faster than a C++ virtual method call (both of which are slower than a non-virtual method call, inline code, or a C function call of course).
[1] https://www.mikeash.com/pyblog/performance-comparisons-of-co...
It's when you start to have to use signals thousands of times per event that it becomes a problem.
Signals for raw user events won't make a difference, but signals as the main mechanism of API interfacing is a problem.
I would say it's a serious problem.
I avoid using signals in general.
You're going to be using up, what, 300 microseconds?
But even then, you're missing the point, because you don't have to use signals to detect the mouse moving if you don't want to.
Like, I’m fairly sure you could have decent latency if your callback function for onMouseMove made a local network call to another process.
Also, how fast do you think download progress should update? Animating it to the next keyframe every second is much more than enough.
But for clicking the mouse, scrolling a page, kicking off a network request - you could go up to a full ms and you'd still feel that the app is (in a vague general sense) "performant".
Having written a few kioslaves decades ago, I feel pretty qualified to comment on Qt's signal/slot performance. Similar to select and poll, QSocketNotifier fires off a signal when there's data ready on an fd. Typically you won't see an event per byte with either interface (unless you're deliberately writing obtuse code).
I think that a lot of the "Qt is slow" nonsense came from C++'s awful reputation especially when it came to templates. The reality was that signals/slots were always a slick and performant wrapper around callbacks. It's worth noting that Qt in all its glory is available on QNX (a well known RTOS) and has been since 4.6. Performance is a non-issue.
Insofar as other overhead sensitive environments go, Trolltech ported Qt (including the signal/slot paradigm) to a realtime OS (QNX) and features it prominently in safety critical contexts (e.g. automotive dashboards).
I wonder who thought signals were fast to begin with?
You're surprised signals are fairly low overhead (and that's fine) and and wondered if anyone actually thought they were performant. Having dabbled with Qt off and on for decades I wasn't surprised. The beauty of moc is that it front loads a lot of the magic. Compiling it sucks (less now), running it typically doesn't.(I believe the reason why it doesn't quite work that way in practice is because slot dispatch is ID-based, not pointer-based.)
Computers work faster than people who click manually.
Sounds like the guy who wanted an event to be fired for each audio sample and required 44100 samples per second. Interestingly, qt signals maybe even fast enough for just that.
Signals are good for rare, unpredictable events. If you have a firehose worth of data coming in, you're not sitting around waiting very often. Your data probably also has some commonality to it, and can be handled in bulk. If you have 100K events coming in, they're probably events of the same type.
Just like if you're writing gigabytes to a file, a program written with the most minimum amount of intelligence isn't going to do it one character at a time.
Also to process important incoming messages on the same thread as the main event loop - where other things like user input, application drawing is handled, is kind of a bad idea.