Possible events performance optimizations
- Jan Tvrdík
- Nette guru | 2595
Events in Nette are not slow, but they could be faster. The
most expensive part of event invocation (assuming ac853ac
will get merged) is ObjectMixin::hasProperty
(more than 50 % in
the worst case scenario, which is also the most-common scenario in Nette
itself).
The problem is that even though the caller (e.g.
Nette\Application\Application
) knows that he's calling event
stored in public property, ObjectMixin
does not know that and
therefore has to use reflection to verify that.
There are two possible optimization that crossed my mind:
1) Optimize the worst case / most-common scenario
Instead of $this->onClick(...)
use
$this->onClick && $this->onClick(...)
.
2) Add new method for fast event call
public static function fireEvent($event, $args)
{
if (is_array($event) || $event instanceof \Traversable) {
foreach ($event as $handler) {
Callback::invokeArgs($handler, $args);
}
}
}
And use
WhatEver::fireEvent($this->onClick, ...);
Does this make sense to you or do you consider current event implementation fast enough?
Last edited by Jan Tvrdík (2014-11-10 17:04)
- Jan Tvrdík
- Nette guru | 2595
Currently (assuming ac853ac will get merged) 100 worst-case (unique) event calls takes about 1 ms.
Speedup #1 – check for empty is about 10-times faster in worst-case scenario and makes no difference in base-case scenario.
Speedup #2 – fast event call (WhatEver::fireEvent
) is about
10-times faster in worst-case scenario and about 5-times faster in best-case
scenario.
Last edited by Jan Tvrdík (2014-11-10 18:19)
- David Grudl
- Nette Core | 8228
Invoking and checking callbacks can be changed (with (nearly) no BC break) this way
from:
public static function invokeArgs($callable, array $args = array())
{
self::check($callable);
return call_user_func_array($callable, $args);
}
to:
public static function invokeArgs($callable, array $args = array())
{
if (($res = call_user_func_array($callable, $args)) === FALSE) {
self::check($callable);
}
return $res;
}
But without measurement I can not guess that the latter will be faster.
- Jan Tvrdík
- Nette guru | 2595
@DavidGrudl Yes, that is faster. Assuming one listener per event it makes every event call about 10 % faster in best-case scenario and about 5 % faster in worst-case scenario*.
With fast-event call is difference even bigger.
*Therefore it is much less significant than not using
preg_match
=)
Last edited by Jan Tvrdík (2014-11-10 19:20)