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 f157a24

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

File tree

3 files changed

+52
-9
lines changed
Filter options

3 files changed

+52
-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
+44-6Lines changed: 44 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,9 @@ 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+
if (isset($this->sorted[$eventName]) || isset($this->optimized[$eventName])) {
141+
unset($this->sorted[$eventName], $this->optimized[$eventName]);
142+
}
127143
}
128144

129145
/**
@@ -145,7 +161,7 @@ public function removeListener($eventName, $listener)
145161
$v[0] = $v[0]();
146162
}
147163
if ($v === $listener) {
148-
unset($listeners[$k], $this->sorted[$eventName]);
164+
unset($listeners[$k], $this->sorted[$eventName], $this->optimized[$eventName]);
149165
} else {
150166
$listeners[$k] = $v;
151167
}
@@ -215,10 +231,8 @@ protected function doDispatch($listeners, $eventName, Event $event)
215231

216232
/**
217233
* Sorts the internal list of listeners for the given event by priority.
218-
*
219-
* @param string $eventName The name of the event
220234
*/
221-
private function sortListeners($eventName)
235+
private function sortListeners(string $eventName)
222236
{
223237
krsort($this->listeners[$eventName]);
224238
$this->sorted[$eventName] = array();
@@ -233,4 +247,28 @@ private function sortListeners($eventName)
233247
}
234248
}
235249
}
250+
251+
/**
252+
* Optimizes the internal list of listeners for the given event by priority.
253+
*/
254+
private function optimizeListeners(string $eventName): array
255+
{
256+
krsort($this->listeners[$eventName]);
257+
$optimized = &$this->optimized[$eventName];
258+
$optimized = array();
259+
260+
foreach ($this->listeners[$eventName] as &$listeners) {
261+
foreach ($listeners as &$listener) {
262+
$closure = &$optimized[];
263+
$closure = $listener instanceof \Closure ? $listener : static function (...$args) use (&$listener, &$closure) {
264+
if (\is_array($listener) && $listener[0] instanceof \Closure) {
265+
$listener[0] = $listener[0]();
266+
}
267+
($closure = \Closure::fromCallable($listener))(...$args);
268+
};
269+
}
270+
}
271+
272+
return $optimized;
273+
}
236274
}

‎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.