From c86efa6caade8aa6a1507012ccb9522eb554dfe1 Mon Sep 17 00:00:00 2001 From: Jarek Tkaczyk Date: Mon, 26 Feb 2018 22:08:34 +0800 Subject: [PATCH] added instance cache for wildcard listeners in order to save on expensive Str::is calls, which usually goes in dozens of thousands --- src/Illuminate/Events/Dispatcher.php | 17 +++++++++++++---- tests/Events/EventsDispatcherTest.php | 17 +++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/Illuminate/Events/Dispatcher.php b/src/Illuminate/Events/Dispatcher.php index d99031cf0269..27dcfbfbf12b 100755 --- a/src/Illuminate/Events/Dispatcher.php +++ b/src/Illuminate/Events/Dispatcher.php @@ -36,6 +36,13 @@ class Dispatcher implements DispatcherContract */ protected $wildcards = []; + /** + * Wildcard listeners cache which saves expensive string operations. + * + * @var array + */ + protected $wildcardsCache = []; + /** * The queue resolver instance. * @@ -82,6 +89,8 @@ public function listen($events, $listener) protected function setupWildcardListen($event, $listener) { $this->wildcards[$event][] = $this->makeListener($listener, true); + + $this->wildcardsCache = []; } /** @@ -281,9 +290,9 @@ public function getListeners($eventName) { $listeners = $this->listeners[$eventName] ?? []; - $listeners = array_merge( - $listeners, $this->getWildcardListeners($eventName) - ); + $wildcardListeners = $this->wildcardsCache[$eventName] ?? $this->getWildcardListeners($eventName); + + $listeners = array_merge($listeners, $wildcardListeners); return class_exists($eventName, false) ? $this->addInterfaceListeners($eventName, $listeners) @@ -306,7 +315,7 @@ protected function getWildcardListeners($eventName) } } - return $wildcards; + return $this->wildcardsCache[$eventName] = $wildcards; } /** diff --git a/tests/Events/EventsDispatcherTest.php b/tests/Events/EventsDispatcherTest.php index d0da1a7a6d7c..896c0231a50c 100755 --- a/tests/Events/EventsDispatcherTest.php +++ b/tests/Events/EventsDispatcherTest.php @@ -104,6 +104,23 @@ public function testWildcardListeners() $this->assertEquals('wildcard', $_SERVER['__event.test']); } + public function testWildcardListenersCacheFlushing() + { + unset($_SERVER['__event.test']); + $d = new Dispatcher; + $d->listen('foo.*', function () { + $_SERVER['__event.test'] = 'cached_wildcard'; + }); + $d->fire('foo.bar'); + $this->assertEquals('cached_wildcard', $_SERVER['__event.test']); + + $d->listen('foo.*', function () { + $_SERVER['__event.test'] = 'new_wildcard'; + }); + $d->fire('foo.bar'); + $this->assertEquals('new_wildcard', $_SERVER['__event.test']); + } + public function testListenersCanBeRemoved() { unset($_SERVER['__event.test']);