Add 'php/phpxmlrpc/' from commit 'cd5dbb4a511e7a616a61187a5de1a611a9748cbd'
[plcapi.git] / php / phpxmlrpc / tests / benchmark.php
1 <?php
2 /**
3  * Benchmarking suite for the PHP-XMLRPC lib.
4  *
5  * @author Gaetano Giunta
6  * @copyright (c) 2005-2015 G. Giunta
7  * @license code licensed under the BSD License: see file license.txt
8  *
9  * @todo add a test for response ok in call testing
10  * @todo add support for --help option to give users the list of supported parameters
11  **/
12
13 use PhpXmlRpc\PhpXmlRpc;
14 use PhpXmlRpc\Value;
15 use PhpXmlRpc\Request;
16 use PhpXmlRpc\Client;
17 use PhpXmlRpc\Response;
18 use PhpXmlRpc\Encoder;
19
20 include_once __DIR__ . '/../vendor/autoload.php';
21
22 include __DIR__ . '/parse_args.php';
23 $args = argParser::getArgs();
24
25 function begin_test($test_name, $test_case)
26 {
27     global $test_results;
28     if (!isset($test_results[$test_name])) {
29         $test_results[$test_name] = array();
30     }
31     $test_results[$test_name][$test_case] = array();
32     $test_results[$test_name][$test_case]['time'] = microtime(true);
33 }
34
35 function end_test($test_name, $test_case, $test_result)
36 {
37     global $test_results;
38     $end = microtime(true);
39     if (!isset($test_results[$test_name][$test_case])) {
40         trigger_error('ending test that was not started');
41     }
42     $test_results[$test_name][$test_case]['time'] = $end - $test_results[$test_name][$test_case]['time'];
43     $test_results[$test_name][$test_case]['result'] = $test_result;
44     echo '.';
45     flush();
46     @ob_flush();
47 }
48
49 // Set up PHP structures to be used in many tests
50
51 $data1 = array(1, 1.0, 'hello world', true, '20051021T23:43:00', -1, 11.0, '~!@#$%^&*()_+|', false, '20051021T23:43:00');
52 $data2 = array('zero' => $data1, 'one' => $data1, 'two' => $data1, 'three' => $data1, 'four' => $data1, 'five' => $data1, 'six' => $data1, 'seven' => $data1, 'eight' => $data1, 'nine' => $data1);
53 $data = array($data2, $data2, $data2, $data2, $data2, $data2, $data2, $data2, $data2, $data2);
54 $keys = array('zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine');
55
56 // Begin execution
57
58 $test_results = array();
59 $is_web = isset($_SERVER['REQUEST_METHOD']);
60 $xd = extension_loaded('xdebug') && ini_get('xdebug.profiler_enable');
61 if ($xd) {
62     $num_tests = 1;
63 } else {
64     $num_tests = 10;
65 }
66
67 $title = 'XML-RPC Benchmark Tests';
68
69 if ($is_web) {
70     echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\" xml:lang=\"en\">\n<head>\n<title>$title</title>\n</head>\n<body>\n<h1>$title</h1>\n<pre>\n";
71 } else {
72     echo "$title\n\n";
73 }
74
75 if ($is_web) {
76     echo "<h3>Using lib version: " . PhpXmlRpc::$xmlrpcVersion . " on PHP version: " . phpversion() . "</h3>\n";
77     if ($xd) {
78         echo "<h4>XDEBUG profiling enabled: skipping remote tests. Trace file is: " . htmlspecialchars(xdebug_get_profiler_filename()) . "</h4>\n";
79     }
80     flush();
81     ob_flush();
82 } else {
83     echo "Using lib version: " . PhpXmlRpc::$xmlrpcVersion . " on PHP version: " . phpversion() . "\n";
84     if ($xd) {
85         echo "XDEBUG profiling enabled: skipping remote tests\nTrace file is: " . xdebug_get_profiler_filename() . "\n";
86     }
87 }
88
89 // test 'manual style' data encoding vs. 'automatic style' encoding
90 begin_test('Data encoding (large array)', 'manual encoding');
91 for ($i = 0; $i < $num_tests; $i++) {
92     $vals = array();
93     for ($j = 0; $j < 10; $j++) {
94         $valarray = array();
95         foreach ($data[$j] as $key => $val) {
96             $values = array();
97             $values[] = new Value($val[0], 'int');
98             $values[] = new Value($val[1], 'double');
99             $values[] = new Value($val[2], 'string');
100             $values[] = new Value($val[3], 'boolean');
101             $values[] = new Value($val[4], 'dateTime.iso8601');
102             $values[] = new Value($val[5], 'int');
103             $values[] = new Value($val[6], 'double');
104             $values[] = new Value($val[7], 'string');
105             $values[] = new Value($val[8], 'boolean');
106             $values[] = new Value($val[9], 'dateTime.iso8601');
107             $valarray[$key] = new Value($values, 'array');
108         }
109         $vals[] = new Value($valarray, 'struct');
110     }
111     $value = new Value($vals, 'array');
112     $out = $value->serialize();
113 }
114 end_test('Data encoding (large array)', 'manual encoding', $out);
115
116 begin_test('Data encoding (large array)', 'automatic encoding');
117 $encoder = new Encoder();
118 for ($i = 0; $i < $num_tests; $i++) {
119     $value = $encoder->encode($data, array('auto_dates'));
120     $out = $value->serialize();
121 }
122 end_test('Data encoding (large array)', 'automatic encoding', $out);
123
124 if (function_exists('xmlrpc_set_type')) {
125     begin_test('Data encoding (large array)', 'xmlrpc-epi encoding');
126     for ($i = 0; $i < $num_tests; $i++) {
127         for ($j = 0; $j < 10; $j++) {
128             foreach ($keys as $k) {
129                 xmlrpc_set_type($data[$j][$k][4], 'datetime');
130                 xmlrpc_set_type($data[$j][$k][8], 'datetime');
131             }
132         }
133         $out = xmlrpc_encode($data);
134     }
135     end_test('Data encoding (large array)', 'xmlrpc-epi encoding', $out);
136 }
137
138 // test 'old style' data decoding vs. 'automatic style' decoding
139 $dummy = new Request('');
140 $out = new Response($value);
141 $in = '<?xml version="1.0" ?>' . "\n" . $out->serialize();
142
143 begin_test('Data decoding (large array)', 'manual decoding');
144 for ($i = 0; $i < $num_tests; $i++) {
145     $response = $dummy->ParseResponse($in, true);
146     $value = $response->value();
147     $result = array();
148     foreach($value as $val1) {
149         $out = array();
150         foreach($val1 as $name => $val) {
151             $out[$name] = array();
152             foreach($val as $data) {
153                 $out[$name][] = $data->scalarval();
154             }
155         }
156         $result[] = $out;
157     }
158 }
159 end_test('Data decoding (large array)', 'manual decoding', $result);
160
161 begin_test('Data decoding (large array)', 'manual decoding deprecated');
162 for ($i = 0; $i < $num_tests; $i++) {
163     $response = $dummy->ParseResponse($in, true);
164     $value = $response->value();
165     $result = array();
166     $l = $value->arraysize();
167     for ($k = 0; $k < $l; $k++) {
168         $val1 = $value->arraymem($k);
169         $out = array();
170         while (list($name, $val) = $val1->structeach()) {
171             $out[$name] = array();
172             $m = $val->arraysize();
173             for ($j = 0; $j < $m; $j++) {
174                 $data = $val->arraymem($j);
175                 $out[$name][] = $data->scalarval();
176             }
177         } // while
178         $result[] = $out;
179     }
180 }
181 end_test('Data decoding (large array)', 'manual decoding deprecated', $result);
182
183 begin_test('Data decoding (large array)', 'automatic decoding');
184 for ($i = 0; $i < $num_tests; $i++) {
185     $response = $dummy->ParseResponse($in, true, 'phpvals');
186     $value = $response->value();
187 }
188 end_test('Data decoding (large array)', 'automatic decoding', $value);
189
190 if (function_exists('xmlrpc_decode')) {
191     begin_test('Data decoding (large array)', 'xmlrpc-epi decoding');
192     for ($i = 0; $i < $num_tests; $i++) {
193         $response = $dummy->ParseResponse($in, true, 'xml');
194         $value = xmlrpc_decode($response->value());
195     }
196     end_test('Data decoding (large array)', 'xmlrpc-epi decoding', $value);
197 }
198
199 if (!$xd) {
200
201     /// test multicall vs. many calls vs. keep-alives
202     $encoder = new Encoder();
203     $value = $encoder->encode($data1, array('auto_dates'));
204     $req = new Request('interopEchoTests.echoValue', array($value));
205     $reqs = array();
206     for ($i = 0; $i < 25; $i++) {
207         $reqs[] = $req;
208     }
209     $server = explode(':', $args['LOCALSERVER']);
210     if (count($server) > 1) {
211         $srv = $server[1] . '://' . $server[0] . $args['URI'];
212         $c = new Client($args['URI'], $server[0], $server[1]);
213     } else {
214         $srv = $args['LOCALSERVER'] . $args['URI'];
215         $c = new Client($args['URI'], $args['LOCALSERVER']);
216     }
217     // do not interfere with http compression
218     $c->accepted_compression = array();
219     //$c->debug=true;
220
221     $testName = "Repeated send (small array) to $srv";
222
223     if (function_exists('gzinflate')) {
224         $c->accepted_compression = null;
225     }
226     begin_test($testName, 'http 10');
227     $response = array();
228     for ($i = 0; $i < 25; $i++) {
229         $resp = $c->send($req);
230         $response[] = $resp->value();
231     }
232     end_test($testName, 'http 10', $response);
233
234     if (function_exists('curl_init')) {
235         begin_test($testName, 'http 11 w. keep-alive');
236         $response = array();
237         for ($i = 0; $i < 25; $i++) {
238             $resp = $c->send($req, 10, 'http11');
239             $response[] = $resp->value();
240         }
241         end_test($testName, 'http 11 w. keep-alive', $response);
242
243         $c->keepalive = false;
244         begin_test($testName, 'http 11');
245         $response = array();
246         for ($i = 0; $i < 25; $i++) {
247             $resp = $c->send($req, 10, 'http11');
248             $response[] = $resp->value();
249         }
250         end_test($testName, 'http 11', $response);
251     }
252
253     begin_test($testName, 'multicall');
254     $response = $c->send($reqs);
255     foreach ($response as $key => & $val) {
256         $val = $val->value();
257     }
258     end_test($testName, 'multicall', $response);
259
260     if (function_exists('gzinflate')) {
261         $c->accepted_compression = array('gzip');
262         $c->request_compression = 'gzip';
263
264         begin_test($testName, 'http 10 w. compression');
265         $response = array();
266         for ($i = 0; $i < 25; $i++) {
267             $resp = $c->send($req);
268             $response[] = $resp->value();
269         }
270         end_test($testName, 'http 10 w. compression', $response);
271
272         if (function_exists('curl_init')) {
273             begin_test($testName, 'http 11 w. keep-alive and compression');
274             $response = array();
275             for ($i = 0; $i < 25; $i++) {
276                 $resp = $c->send($req, 10, 'http11');
277                 $response[] = $resp->value();
278             }
279             end_test($testName, 'http 11 w. keep-alive and compression', $response);
280
281             $c->keepalive = false;
282             begin_test($testName, 'http 11 w. compression');
283             $response = array();
284             for ($i = 0; $i < 25; $i++) {
285                 $resp = $c->send($req, 10, 'http11');
286                 $response[] = $resp->value();
287             }
288             end_test($testName, 'http 11 w. compression', $response);
289         }
290
291         begin_test($testName, 'multicall w. compression');
292         $response = $c->send($reqs);
293         foreach ($response as $key => & $val) {
294             $val = $val->value();
295         }
296         end_test($testName, 'multicall w. compression', $response);
297     }
298 } // end of 'if no xdebug profiling'
299
300
301 echo "\n";
302 foreach ($test_results as $test => $results) {
303     echo "\nTEST: $test\n";
304     foreach ($results as $case => $data) {
305         echo "  $case: {$data['time']} secs - Output data CRC: " . crc32(serialize($data['result'])) . "\n";
306     }
307 }
308
309 if ($is_web) {
310     echo "\n</pre>\n</body>\n</html>\n";
311 }