Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 5bc59f1

Browse filesBrowse files
[EventDispatcher][VarDumper] optimize perf by leveraging Closure::fromCallable()
1 parent dbf053b commit 5bc59f1
Copy full SHA for 5bc59f1

File tree

3 files changed

+54
-9
lines changed
Filter options

3 files changed

+54
-9
lines changed

‎src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php
+4-2Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
class WrappedListener
2323
{
2424
private $listener;
25+
private $optimizedListener;
2526
private $name;
2627
private $called;
2728
private $stoppedPropagation;
@@ -31,9 +32,10 @@ class WrappedListener
3132
private $stub;
3233
private static $hasClassStub;
3334

34-
public function __construct($listener, $name, Stopwatch $stopwatch, EventDispatcherInterface $dispatcher = null)
35+
public function __construct(callable $listener, ?string $name, Stopwatch $stopwatch, EventDispatcherInterface $dispatcher = null)
3536
{
3637
$this->listener = $listener;
38+
$this->optimizedListener = $listener instanceof \Closure ? $listener : \Closure::fromCallable($listener);
3739
$this->stopwatch = $stopwatch;
3840
$this->dispatcher = $dispatcher;
3941
$this->called = false;
@@ -108,7 +110,7 @@ public function __invoke(Event $event, $eventName, EventDispatcherInterface $dis
108110

109111
$e = $this->stopwatch->start($this->name, 'event_listener');
110112

111-
\call_user_func($this->listener, $event, $eventName, $this->dispatcher ?: $dispatcher);
113+
\call_user_func($this->optimizedListener, $event, $eventName, $this->dispatcher ?: $dispatcher);
112114

113115
if ($e->isStarted()) {
114116
$e->stop();

‎src/Symfony/Component/EventDispatcher/EventDispatcher.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/EventDispatcher/EventDispatcher.php
+46-6Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ class EventDispatcher implements EventDispatcherInterface
3030
{
3131
private $listeners = array();
3232
private $sorted = array();
33+
private $optimized;
34+
35+
public function __construct()
36+
{
37+
if (__CLASS__ === \get_class($this)) {
38+
$this->optimized = array();
39+
}
40+
}
3341

3442
/**
3543
* {@inheritdoc}
@@ -40,7 +48,13 @@ public function dispatch($eventName, Event $event = null)
4048
$event = new Event();
4149
}
4250

43-
if ($listeners = $this->getListeners($eventName)) {
51+
if (null !== $this->optimized && null !== $eventName) {
52+
$listeners = $this->optimized[$eventName] ?? (empty($this->listeners[$eventName]) ? array() : $this->optimizeListeners($eventName));
53+
} else {
54+
$listeners = $this->getListeners($eventName);
55+
}
56+
57+
if ($listeners) {
4458
$this->doDispatch($listeners, $eventName, $event);
4559
}
4660

@@ -123,7 +137,7 @@ public function hasListeners($eventName = null)
123137
public function addListener($eventName, $listener, $priority = 0)
124138
{
125139
$this->listeners[$eventName][$priority][] = $listener;
126-
unset($this->sorted[$eventName]);
140+
unset($this->sorted[$eventName], $this->optimized[$eventName]);
127141
}
128142

129143
/**
@@ -145,7 +159,7 @@ public function removeListener($eventName, $listener)
145159
$v[0] = $v[0]();
146160
}
147161
if ($v === $listener) {
148-
unset($listeners[$k], $this->sorted[$eventName]);
162+
unset($listeners[$k], $this->sorted[$eventName], $this->optimized[$eventName]);
149163
} else {
150164
$listeners[$k] = $v;
151165
}
@@ -215,10 +229,8 @@ protected function doDispatch($listeners, $eventName, Event $event)
215229

216230
/**
217231
* Sorts the internal list of listeners for the given event by priority.
218-
*
219-
* @param string $eventName The name of the event
220232
*/
221-
private function sortListeners($eventName)
233+
private function sortListeners(string $eventName)
222234
{
223235
krsort($this->listeners[$eventName]);
224236
$this->sorted[$eventName] = array();
@@ -233,4 +245,32 @@ private function sortListeners($eventName)
233245
}
234246
}
235247
}
248+
249+
/**
250+
* Optimizes the internal list of listeners for the given event by priority.
251+
*/
252+
private function optimizeListeners(string $eventName): array
253+
{
254+
krsort($this->listeners[$eventName]);
255+
$optimized = &$this->optimized[$eventName];
256+
$optimized = array();
257+
258+
foreach ($this->listeners[$eventName] as &$listeners) {
259+
foreach ($listeners as &$listener) {
260+
$closure = &$optimized[];
261+
if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) {
262+
$closure = static function (...$args) use (&$listener, &$closure) {
263+
if ($listener[0] instanceof \Closure) {
264+
$listener[0] = $listener[0]();
265+
}
266+
($closure = \Closure::fromCallable($listener))(...$args);
267+
};
268+
} else {
269+
$closure = $listener instanceof \Closure ? $listener : \Closure::fromCallable($listener);
270+
}
271+
}
272+
}
273+
274+
return $optimized;
275+
}
236276
}

‎src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php
+4-1Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,10 @@ public function __construct(array $casters = null)
176176
public function addCasters(array $casters)
177177
{
178178
foreach ($casters as $type => $callback) {
179-
$this->casters[strtolower($type)][] = \is_string($callback) && false !== strpos($callback, '::') ? explode('::', $callback, 2) : $callback;
179+
$closure = &$this->casters[strtolower($type)][];
180+
$closure = $callback instanceof \Closure ? $callback : static function (...$args) use ($callback, &$closure) {
181+
return ($closure = \Closure::fromCallable($callback))(...$args);
182+
};
180183
}
181184
}
182185

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.