|
9 | 9 |
|
10 | 10 | use Rx\Observable; |
11 | 11 | use Rx\Observer\CallbackObserver; |
| 12 | +use React\EventLoop\LoopInterface; |
12 | 13 |
|
13 | 14 | // Check whether XDebug is enabled |
14 | 15 | if (in_array('Xdebug', get_loaded_extensions(true))) { |
|
47 | 48 | printf('%s', pathinfo($file, PATHINFO_FILENAME)); |
48 | 49 | }) |
49 | 50 | ->map(function($file) { // Run benchmark |
50 | | - $totalDuration = 0.0; |
51 | 51 | $durations = []; |
| 52 | + /** @var Observable $observable */ |
| 53 | + $observable = null; |
| 54 | + /** @var LoopInterface $loop */ |
| 55 | + $loop = null; |
| 56 | + /** @var callable(): Observable $sourceFactory */ |
| 57 | + $sourceFactory = null; |
52 | 58 |
|
53 | 59 | ob_start(); |
54 | 60 |
|
55 | | - $dummyObserver = new Rx\Observer\CallbackObserver( |
56 | | - function ($value) { }, |
57 | | - function ($error) { }, |
58 | | - function () { } |
59 | | - ); |
| 61 | + $testDef = @include $file; |
60 | 62 |
|
61 | | - $testClosure = @include $file; |
62 | | - if (!$testClosure) { |
63 | | - throw new Exception("Unable to load file \"$file\""); |
| 63 | + if (is_array($testDef)) { |
| 64 | + $sourceFactory = $testDef[0]; |
| 65 | + $loop = $testDef[1]; |
| 66 | + } elseif (is_callable($testDef)) { |
| 67 | + $sourceFactory = $testDef; |
| 68 | + } else { |
| 69 | + throw new Exception("File \"$file\" doesn't contain a valid benchmark"); |
64 | 70 | } |
65 | 71 |
|
66 | 72 | $memoryUsage = [memory_get_usage()]; |
67 | 73 |
|
68 | | - while ($totalDuration < MIN_TOTAL_DURATION) { |
69 | | - $start = microtime(true); |
70 | | - |
71 | | - $testClosure(); |
72 | | - |
73 | | - $duration = microtime(true) - $start; |
| 74 | + $benchmarkLoop = function(Observable $observable) use (&$durations, &$memoryUsage) { |
| 75 | + $dummyObserver = new Rx\Observer\CallbackObserver( |
| 76 | + function ($value) { }, |
| 77 | + function ($error) { }, |
| 78 | + function () use (&$start, &$durations) { |
| 79 | + $durations[] = (microtime(true) - $start) * 1000; |
| 80 | + } |
| 81 | + ); |
74 | 82 |
|
75 | | - $durations[] = $duration * 1000; |
76 | | - $totalDuration += $duration; |
| 83 | + $start = microtime(true); |
| 84 | + $observable->subscribe($dummyObserver); |
77 | 85 |
|
78 | 86 | if (count($durations) === 100) { |
79 | 87 | $memoryUsage[] = memory_get_usage(); |
80 | 88 | } |
| 89 | + }; |
| 90 | + |
| 91 | + $stopStartTime = microtime(true) + MIN_TOTAL_DURATION; |
| 92 | + |
| 93 | + if ($loop) { |
| 94 | + $reschedule = function() use (&$reschedule, $benchmarkLoop, $sourceFactory, $loop, $stopStartTime) { |
| 95 | + $loop->futureTick(function () use (&$reschedule, $benchmarkLoop, $stopStartTime, $sourceFactory) { |
| 96 | + $benchmarkLoop($sourceFactory()); |
| 97 | + if ($stopStartTime > microtime(true)) { |
| 98 | + $reschedule(); |
| 99 | + } |
| 100 | + }); |
| 101 | + }; |
| 102 | + |
| 103 | + $reschedule(); |
| 104 | + $loop->run(); |
| 105 | + } else { |
| 106 | + while ($stopStartTime > microtime(true)) { |
| 107 | + $benchmarkLoop($sourceFactory()); |
| 108 | + } |
81 | 109 | } |
82 | 110 |
|
83 | 111 | $memoryUsage[] = memory_get_usage(); |
|
0 commit comments