Skip to content

Commit

Permalink
Optimisation wildcardEmitter. added benchmark. Closes #49.
Browse files Browse the repository at this point in the history
  • Loading branch information
jf authored and staabm committed Jun 10, 2017
1 parent 0ceba38 commit d11683c
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 16 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
ChangeLog
=========
5.0.2 (2017-04-29)

* optimisation for EmitterTrait and WildcardEmitterTrait (@lunixyacht).

5.0.1 (2016-10-29)
------------------
Expand Down
1 change: 1 addition & 0 deletions _config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
theme: jekyll-theme-cayman
2 changes: 1 addition & 1 deletion lib/Version.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ class Version {
/**
* Full version number
*/
const VERSION = '5.0.1';
const VERSION = '5.0.2';

}
30 changes: 15 additions & 15 deletions lib/WildcardEmitterTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ trait WildcardEmitterTrait {
function on(string $eventName, callable $callBack, int $priority = 100) {

// If it ends with a wildcard, we use the wildcardListeners array
if ($eventName[strlen($eventName) - 1] === '*') {
$eventName = substr($eventName, 0, -1);
if ($eventName[\strlen($eventName) - 1] === '*') {
$eventName = \substr($eventName, 0, -1);
$listeners = & $this->wildcardListeners;
} else {
$listeners = & $this->listeners;
Expand Down Expand Up @@ -58,7 +58,7 @@ function once(string $eventName, callable $callBack, int $priority = 100) {
$wrapper = function() use ($eventName, $callBack, &$wrapper) {

$this->removeListener($eventName, $wrapper);
return call_user_func_array($callBack, func_get_args());
return \call_user_func_array($callBack, \func_get_args());

};

Expand Down Expand Up @@ -89,11 +89,11 @@ function once(string $eventName, callable $callBack, int $priority = 100) {
*/
function emit(string $eventName, array $arguments = [], callable $continueCallBack = null) : bool {

if (is_null($continueCallBack)) {
if (\is_null($continueCallBack)) {

foreach ($this->listeners($eventName) as $listener) {

$result = call_user_func_array($listener, $arguments);
$result = \call_user_func_array($listener, $arguments);
if ($result === false) {
return false;
}
Expand All @@ -102,12 +102,12 @@ function emit(string $eventName, array $arguments = [], callable $continueCallBa
} else {

$listeners = $this->listeners($eventName);
$counter = count($listeners);
$counter = \count($listeners);

foreach ($listeners as $listener) {

$counter--;
$result = call_user_func_array($listener, $arguments);
$result = \call_user_func_array($listener, $arguments);
if ($result === false) {
return false;
}
Expand Down Expand Up @@ -135,7 +135,7 @@ function emit(string $eventName, array $arguments = [], callable $continueCallBa
*/
function listeners(string $eventName) : array {

if (!array_key_exists($eventName, $this->listenerIndex)) {
if (!\array_key_exists($eventName, $this->listenerIndex)) {

// Create a new index.
$listeners = [];
Expand All @@ -150,7 +150,7 @@ function listeners(string $eventName) : array {
foreach ($this->wildcardListeners as $wcEvent => $wcListeners) {

// Wildcard match
if (substr($eventName, 0, strlen($wcEvent)) === $wcEvent) {
if (\substr($eventName, 0, \strlen($wcEvent)) === $wcEvent) {

foreach ($wcListeners as $listener) {

Expand All @@ -164,7 +164,7 @@ function listeners(string $eventName) : array {
}

// Sorting by priority
array_multisort($listenersPriority, SORT_NUMERIC, $listeners);
\array_multisort($listenersPriority, SORT_NUMERIC, $listeners);

// Creating index
$this->listenersIndex[$eventName] = $listeners;
Expand All @@ -184,8 +184,8 @@ function listeners(string $eventName) : array {
function removeListener(string $eventName, callable $listener) : bool {

// If it ends with a wildcard, we use the wildcardListeners array
if ($eventName[strlen($eventName) - 1] === '*') {
$eventName = substr($eventName, 0, -1);
if ($eventName[\strlen($eventName) - 1] === '*') {
$eventName = \substr($eventName, 0, -1);
$listeners = & $this->wildcardListeners;
} else {
$listeners = & $this->listeners;
Expand Down Expand Up @@ -224,15 +224,15 @@ function removeListener(string $eventName, callable $listener) : bool {
*/
function removeAllListeners(string $eventName = null) {

if (is_null($eventName)) {
if (\is_null($eventName)) {
$this->listeners = [];
$this->wildcardListeners = [];

} else {

if ($eventName[strlen($eventName) - 1] === '*') {
if ($eventName[\strlen($eventName) - 1] === '*') {
// Wildcard event
unset($this->wildcardListeners[substr($eventName, 0, -1)]);
unset($this->wildcardListeners[\substr($eventName, 0, -1)]);
} else {
unset($this->listeners[$eventName]);
}
Expand Down
116 changes: 116 additions & 0 deletions tests/benchmark/benchWildcard.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?php declare (strict_types=1);

use Sabre\Event\WildcardEmitter;

include __DIR__ . '/../../vendor/autoload.php';

abstract class BenchMark {

protected $startTime;
protected $iterations = 10000;
protected $totalTime;

function setUp() {

}

abstract function test();

function go() {

$this->setUp();
$this->startTime = microtime(true);
$this->test();
$this->totalTime = microtime(true) - $this->startTime;
return $this->totalTime;

}

}

class OneCallBack extends BenchMark {

protected $emitter;
protected $iterations = 100000;

function setUp() {

$this->emitter = new WildcardEmitter();
$this->emitter->on('foo', function() {
// NOOP
});

}

function test() {

for ($i = 0;$i < $this->iterations;$i++) {
$this->emitter->emit('foo', []);
}

}

}

class ManyCallBacks extends BenchMark {

protected $emitter;

function setUp() {

$this->emitter = new WildcardEmitter();
for ($i = 0;$i < 100;$i++) {
$this->emitter->on('foo', function() {
// NOOP
});
}

}

function test() {

for ($i = 0;$i < $this->iterations;$i++) {
$this->emitter->emit('foo', []);
}

}

}

class ManyPrioritizedCallBacks extends BenchMark {

protected $emitter;

function setUp() {

$this->emitter = new WildcardEmitter();
for ($i = 0;$i < 100;$i++) {
$this->emitter->on('foo', function() {
}, 1000 - $i);
}

}

function test() {

for ($i = 0;$i < $this->iterations;$i++) {
$this->emitter->emit('foo', []);
}

}

}

$tests = [
'OneCallBack',
'ManyCallBacks',
'ManyPrioritizedCallBacks',
];

foreach ($tests as $test) {

$testObj = new $test();
$result = $testObj->go();
echo $test . " " . $result . "\n";

}

0 comments on commit d11683c

Please sign in to comment.