Skip to content

Instantly share code, notes, and snippets.

@Furgas
Created June 5, 2017 12:11
Show Gist options
  • Save Furgas/0663ac47d23c89db496e71cc219b0b22 to your computer and use it in GitHub Desktop.
Save Furgas/0663ac47d23c89db496e71cc219b0b22 to your computer and use it in GitHub Desktop.
Benchmark - array with instanceof vs. typehinted variadic argument vs. separate iterator class
{
"require": {
"phpunit/php-timer": "~1.0"
}
}
<?php
declare(strict_types=1);
include(__DIR__ . '/vendor/autoload.php');
class Foo {
public $bar = 1;
}
class Foos implements \IteratorAggregate, \Countable {
private $foos;
public function __construct(array $foos) {
foreach ($foos as $foo) {
if (!$foo instanceof Foo) {
throw new \TypeError();
}
}
$this->foos = $foos;
}
public function getFoos(): array {
return $this->foos;
}
/**
* @return \ArrayIterator|UserType[]
*/
public function getIterator() {
return new \ArrayIterator($this->foos);
}
public function count(): int {
return count($this->foos);
}
}
function testArray(bool $use_array_map, array $foos): array {
foreach ($foos as $foo) {
if (!$foo instanceof Foo) {
throw new \TypeError();
}
}
if ($use_array_map) {
$new_foos = array_map(
function (Foo $foo): Foo {
return new Foo($foo->bar + 1);
},
$foos
);
} else {
$new_foos = [];
foreach ($foos as $foo) {
$new_foos[] = new Foo($foo->bar + 1);
}
}
return $new_foos;
}
function testVariadic(bool $use_array_map, Foo ...$foos): array {
if ($use_array_map) {
$new_foos = array_map(
function (Foo $foo): Foo {
return new Foo($foo->bar + 1);
},
$foos
);
} else {
$new_foos = [];
foreach ($foos as $foo) {
$new_foos[] = new Foo($foo->bar + 1);
}
}
return $new_foos;
}
function testIterator(bool $use_array_map, Foos $foos): Foos {
if ($use_array_map) {
$new_foos = array_map(
function (Foo $foo): Foo {
return new Foo($foo->bar + 1);
},
iterator_to_array($foos)
);
} else {
$new_foos = [];
foreach ($foos as $foo) {
$new_foos[] = new Foo($foo->bar + 1);
}
}
return new Foos($new_foos);
}
$foos = [];
for ($i = 0; $i < 500000; $i++) {
$foos[] = new Foo();
}
$test = $argv[1] ?? 'array';
$use_array_map = isset($argv[2]) ? true : false;
switch ($test) {
case 'array':
$foos = testArray($use_array_map, $foos);
break;
case 'variadic':
$foos = testVariadic($use_array_map, ...$foos);
break;
case 'iterator':
$foos = testIterator($use_array_map, new Foos($foos));
break;
}
printf("%s\n", PHP_Timer::resourceUsage());
@Furgas
Copy link
Author

Furgas commented Jun 5, 2017

Results with foreach:

# php --version
PHP 7.1.5 (cli) (built: May 17 2017 11:00:13) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies

# php test.php array
Time: 363 ms, Memory: 100.00MB

# php test.php variadic
Time: 431 ms, Memory: 126.00MB

# php test.php iterator
Time: 569 ms, Memory: 118.00MB

Result with array_map:

# php test.php array array_map
Time: 374 ms, Memory: 100.00MB

# php test.php variadic array_map
Time: 455 ms, Memory: 126.00MB

# php test.php iterator array_map
Time: 635 ms, Memory: 118.00MB

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment