"onMouseMove" is a user signal that you would want to be fast. also signals should be used for more than just user input interactions, like "download progress" etc..
Objective-C was doing sufficiently-fast UI updates for it to run well on iPhones 10 years ago, while relying on objc_msgsend, which is _much_ slower than a virtual function call or even a Qt signal.
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, which is _much_ slower than a virtual function call or even a Qt signal.
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.)
There's a chart of various timings here [1] and objc_msgSend is actually pretty efficient (it's received a lot of optimization over the years for obvious reasons).
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).
I like to bang on the drum that as a programmer, you need to understand the sheer number of orders of magnitude you're spanning more than the average programmer does. We so often deal in "10x slower" and "100x" slower that we can forget that it just doesn't matter if we're doing it even a mere 60 times a second. 10x slower on a process that takes 100ms is a problem. 10x slower on a process that takes 10ns requires a lot of looping to become a human-scale problem. There are things that can attain that level of looping, certainly, but it's not everything.
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.
onMouseMove is normally delivered at the video frame rate, 60 fps. The OP's benchmark shows it can deliver around 60M signals per second, so it uses about 1/1000000 of the CPU time. Seems tolerable.
Even if it was delivered at the polling rate, that should never be higher than 1kHz (otherwise you deserve whatever performance issues you get). A virtual function call is 15ns conservatively, so say a signal is 150ns. 1000x is <150us of wasted time, well below observable overhead in any human-centric application.
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.
The slowest number mentioned in the post--"32,562,683 signals [per second] with sender"--works out to about 31 nanoseconds. That's around half a dozen orders of magnitude less than an amount of latency that would be noticeable to a human.
10 times faster than a virtual call is still ridiculously fast on any general purpose CPU made in this century. We often forget how insanely fast they are (and at the same time, I have no idea how we manage to add as much bloat to certain stacks that they make the processor struggle).
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.
In Qt, those sorts of input interactions are mostly handled through virtual function calls, not signals. You're basically referring to QWidget::mouseMoveEvent. https://doc.qt.io/qt-6/qwidget.html#mouseMoveEvent
msbarnett|3 years ago
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.
morelisp|3 years ago
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...
spacedcowboy|3 years ago
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...
ksherlock|3 years ago
eska|3 years ago
thfuran|3 years ago
jerf|3 years ago
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.
tlb|3 years ago
AlotOfReading|3 years ago
saidinesh5|3 years ago
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.
usefulcat|3 years ago
Gibbon1|3 years ago
kaba0|3 years ago
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.
slavik81|3 years ago
jollybean|3 years ago
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.
ehutch79|3 years ago
Quikinterp|3 years ago
rakoo|3 years ago
windows_sucks|3 years ago
sudosysgen|3 years ago
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.
nsonha|3 years ago