1+ <?php
2+ /**
3+ * Comparison script for Coroutines vs Fibers benchmarks
4+ * Run both benchmarks and compare results
5+ */
6+
7+ // Increase memory limit for benchmark
8+ ini_set ('memory_limit ' , '512M ' );
9+
10+ echo "=== Coroutines vs Fibers Comparison === \n\n" ;
11+
12+ // Configuration
13+ $ iterations = 1000 ;
14+ $ switches = 50 ;
15+
16+ echo "Configuration: \n" ;
17+ echo "- Iterations: $ iterations \n" ;
18+ echo "- Switches per iteration: $ switches \n" ;
19+ echo "- Total context switches: " . ($ iterations * $ switches ) . "\n\n" ;
20+
21+ // Function to run external benchmark and capture output
22+ function runBenchmark ($ script ) {
23+ $ output = [];
24+ $ return_var = 0 ;
25+ exec ("php " . __DIR__ . "/ $ script 2>&1 " , $ output , $ return_var );
26+ return [
27+ 'output ' => implode ("\n" , $ output ),
28+ 'success ' => $ return_var === 0
29+ ];
30+ }
31+
32+ // Function to parse benchmark results from output
33+ function parseResults ($ output ) {
34+ $ results = [];
35+
36+ if (preg_match ('/Time: ([0-9.]+) seconds/ ' , $ output , $ matches )) {
37+ $ results ['time ' ] = (float )$ matches [1 ];
38+ }
39+
40+ if (preg_match ('/Switches per second: ([0-9,]+)/ ' , $ output , $ matches )) {
41+ $ results ['switches_per_sec ' ] = (int )str_replace (', ' , '' , $ matches [1 ]);
42+ }
43+
44+ if (preg_match ('/Overhead per switch: ([0-9.]+) μs/ ' , $ output , $ matches )) {
45+ $ results ['overhead_us ' ] = (float )$ matches [1 ];
46+ }
47+
48+ if (preg_match ('/Used for benchmark: ([0-9.]+) MB/ ' , $ output , $ matches )) {
49+ $ results ['memory_mb ' ] = (float )$ matches [1 ];
50+ }
51+
52+ return $ results ;
53+ }
54+
55+ echo "Running coroutines benchmark... \n" ;
56+ $ coroutineResult = runBenchmark ('coroutines_benchmark.php ' );
57+
58+ echo "Running fibers benchmark... \n" ;
59+ $ fiberResult = runBenchmark ('fibers_benchmark.php ' );
60+
61+ echo "\n" . str_repeat ("= " , 60 ) . "\n" ;
62+ echo "COMPARISON RESULTS \n" ;
63+ echo str_repeat ("= " , 60 ) . "\n\n" ;
64+
65+ if (!$ coroutineResult ['success ' ]) {
66+ echo "❌ Coroutines benchmark failed: \n" ;
67+ echo $ coroutineResult ['output ' ] . "\n\n" ;
68+ } else {
69+ echo "✅ Coroutines benchmark completed successfully \n\n" ;
70+ }
71+
72+ if (!$ fiberResult ['success ' ]) {
73+ echo "❌ Fibers benchmark failed: \n" ;
74+ echo $ fiberResult ['output ' ] . "\n\n" ;
75+ } else {
76+ echo "✅ Fibers benchmark completed successfully \n\n" ;
77+ }
78+
79+ // Parse and compare results if both succeeded
80+ if ($ coroutineResult ['success ' ] && $ fiberResult ['success ' ]) {
81+ $ coroutineStats = parseResults ($ coroutineResult ['output ' ]);
82+ $ fiberStats = parseResults ($ fiberResult ['output ' ]);
83+
84+ echo "📊 PERFORMANCE COMPARISON: \n\n" ;
85+
86+ // Time comparison
87+ if (isset ($ coroutineStats ['time ' ]) && isset ($ fiberStats ['time ' ])) {
88+ $ timeRatio = $ fiberStats ['time ' ] / $ coroutineStats ['time ' ];
89+ echo "⏱️ Execution Time: \n" ;
90+ echo " Coroutines: " . number_format ($ coroutineStats ['time ' ], 4 ) . "s \n" ;
91+ echo " Fibers: " . number_format ($ fiberStats ['time ' ], 4 ) . "s \n" ;
92+ if ($ timeRatio > 1 ) {
93+ echo " 🏆 Coroutines are " . number_format ($ timeRatio , 2 ) . "x faster \n\n" ;
94+ } else {
95+ echo " 🏆 Fibers are " . number_format (1 /$ timeRatio , 2 ) . "x faster \n\n" ;
96+ }
97+ }
98+
99+ // Throughput comparison
100+ if (isset ($ coroutineStats ['switches_per_sec ' ]) && isset ($ fiberStats ['switches_per_sec ' ])) {
101+ echo "🚀 Throughput (switches/sec): \n" ;
102+ echo " Coroutines: " . number_format ($ coroutineStats ['switches_per_sec ' ]) . "\n" ;
103+ echo " Fibers: " . number_format ($ fiberStats ['switches_per_sec ' ]) . "\n" ;
104+ $ throughputRatio = $ coroutineStats ['switches_per_sec ' ] / $ fiberStats ['switches_per_sec ' ];
105+ if ($ throughputRatio > 1 ) {
106+ echo " 🏆 Coroutines have " . number_format ($ throughputRatio , 2 ) . "x higher throughput \n\n" ;
107+ } else {
108+ echo " 🏆 Fibers have " . number_format (1 /$ throughputRatio , 2 ) . "x higher throughput \n\n" ;
109+ }
110+ }
111+
112+ // Overhead comparison
113+ if (isset ($ coroutineStats ['overhead_us ' ]) && isset ($ fiberStats ['overhead_us ' ])) {
114+ echo "⚡ Overhead per switch: \n" ;
115+ echo " Coroutines: " . number_format ($ coroutineStats ['overhead_us ' ], 2 ) . " μs \n" ;
116+ echo " Fibers: " . number_format ($ fiberStats ['overhead_us ' ], 2 ) . " μs \n" ;
117+ $ overheadRatio = $ fiberStats ['overhead_us ' ] / $ coroutineStats ['overhead_us ' ];
118+ if ($ overheadRatio > 1 ) {
119+ echo " 🏆 Coroutines have " . number_format ($ overheadRatio , 2 ) . "x lower overhead \n\n" ;
120+ } else {
121+ echo " 🏆 Fibers have " . number_format (1 /$ overheadRatio , 2 ) . "x lower overhead \n\n" ;
122+ }
123+ }
124+
125+ // Memory comparison
126+ if (isset ($ coroutineStats ['memory_mb ' ]) && isset ($ fiberStats ['memory_mb ' ])) {
127+ echo "💾 Memory Usage: \n" ;
128+ echo " Coroutines: " . number_format ($ coroutineStats ['memory_mb ' ], 2 ) . " MB \n" ;
129+ echo " Fibers: " . number_format ($ fiberStats ['memory_mb ' ], 2 ) . " MB \n" ;
130+ $ memoryRatio = $ fiberStats ['memory_mb ' ] / $ coroutineStats ['memory_mb ' ];
131+ if ($ memoryRatio > 1 ) {
132+ echo " 🏆 Coroutines use " . number_format ($ memoryRatio , 2 ) . "x less memory \n\n" ;
133+ } else {
134+ echo " 🏆 Fibers use " . number_format (1 /$ memoryRatio , 2 ) . "x less memory \n\n" ;
135+ }
136+ }
137+ } else {
138+ echo "⚠️ Cannot compare results - one or both benchmarks failed \n" ;
139+ }
140+
141+ echo "💡 Note: Results may vary based on system load and configuration \n" ;
142+ echo "💡 Run multiple times and average results for production comparisons \n" ;
143+
144+ echo "\nComparison completed. \n" ;
0 commit comments