Skip to content

Commit eb6d046

Browse files
committed
Add PerformanceTest and compare with symfony finder.
1 parent b0205ee commit eb6d046

2 files changed

Lines changed: 72 additions & 1 deletion

File tree

packages/class-files-iterator/composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"ext-json": "*"
2525
},
2626
"require-dev": {
27-
"phpunit/phpunit": "^10.5.38"
27+
"phpunit/phpunit": "^10.5.38",
28+
"symfony/finder": "^7.4"
2829
}
2930
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
namespace Ock\ClassFilesIterator\Tests;
4+
5+
use Ock\ClassFilesIterator\NamespaceDirectory;
6+
use PHPUnit\Framework\TestCase;
7+
use Symfony\Component\Finder\Finder;
8+
9+
class PerformanceTest extends TestCase {
10+
11+
public function testPerformance(): void {
12+
$nsdir = NamespaceDirectory::fromKnownClass(TestCase::class)->requireParentN(1);
13+
$dir = $nsdir->getDirectory();
14+
$tick = $this->stopwatch();
15+
$dts = [];
16+
17+
for ($i = 0; $i < 10; ++$i) {
18+
$it = new \RecursiveDirectoryIterator($dir, \FilesystemIterator::SKIP_DOTS);
19+
$itt = new \RecursiveIteratorIterator($it, \RecursiveIteratorIterator::CHILD_FIRST);
20+
$itt_files = iterator_to_array($itt);
21+
$dts['itt'][] = $tick();
22+
23+
$finder = Finder::create()->files()->name('*.php')->in($dir);
24+
$n_finder = iterator_count($finder);
25+
$dts['finder'][] = $tick();
26+
27+
$n_nsdir = iterator_count($nsdir);
28+
$dts['nsdir'][] = $tick();
29+
}
30+
31+
$itt_php_files = preg_grep('#\.php$#', $itt_files);
32+
$n_itt = count($itt_php_files);
33+
$this->assertGreaterThan(300, $n_itt);
34+
$this->assertLessThan(3000, $n_itt);
35+
$this->assertSame($n_itt, $n_finder);
36+
$this->assertSame($n_itt, $n_nsdir);
37+
38+
$dt_counts = array_map(count(...), $dts);
39+
$this->assertSame([], array_diff($dt_counts, [10]));
40+
41+
// For a deterministic operation, the fastest time is usually the most
42+
// reproducible and stable, because it is not impacted by .
43+
$dt_mins = array_map(min(...), $dts);
44+
45+
$dt_ref = $dt_mins['itt'];
46+
$this->assertEqualsWithDeltaFactor(5.4, $dt_mins['finder'] / $dt_ref, .1);
47+
$this->assertEqualsWithDeltaFactor(2,7, $dt_mins['nsdir'] / $dt_ref, .1);
48+
}
49+
50+
protected function assertEqualsWithDeltaFactor(float $expected, float $actual, float $delta): void {
51+
$this->assertLessThan($expected * (1 + $delta), $actual);
52+
$this->assertGreaterThan($expected / (1 + $delta), $actual);
53+
}
54+
55+
/**
56+
* Starts a stopwatch timer.
57+
*
58+
* @return \Closure(): float
59+
* Function which returns milliseconds since previous call.
60+
*/
61+
protected function stopwatch(): \Closure {
62+
$t0 = hrtime(true);
63+
return function () use (&$t0) {
64+
$dt = hrtime(true) - $t0;
65+
$t0 += $dt;
66+
return $dt * .000001;
67+
};
68+
}
69+
70+
}

0 commit comments

Comments
 (0)