1*1b3f573fSAndroid Build Coastguard Worker<?php 2*1b3f573fSAndroid Build Coastguard Worker 3*1b3f573fSAndroid Build Coastguard Workernamespace Google\Protobuf\Benchmark; 4*1b3f573fSAndroid Build Coastguard Workerini_set('memory_limit', '4096M'); 5*1b3f573fSAndroid Build Coastguard Worker 6*1b3f573fSAndroid Build Coastguard Workerconst NAME = "PhpBenchmark.php"; 7*1b3f573fSAndroid Build Coastguard Worker 8*1b3f573fSAndroid Build Coastguard Workerfunction _require_all($dir, &$prefix) { 9*1b3f573fSAndroid Build Coastguard Worker // require all php files 10*1b3f573fSAndroid Build Coastguard Worker foreach (glob("$dir/*") as $path) { 11*1b3f573fSAndroid Build Coastguard Worker if (preg_match('/\.php$/', $path) && 12*1b3f573fSAndroid Build Coastguard Worker substr($path, -strlen(NAME)) != NAME) { 13*1b3f573fSAndroid Build Coastguard Worker require_once(substr($path, strlen($prefix) + 1)); 14*1b3f573fSAndroid Build Coastguard Worker } elseif (is_dir($path)) { 15*1b3f573fSAndroid Build Coastguard Worker _require_all($path, $prefix); 16*1b3f573fSAndroid Build Coastguard Worker } 17*1b3f573fSAndroid Build Coastguard Worker } 18*1b3f573fSAndroid Build Coastguard Worker} 19*1b3f573fSAndroid Build Coastguard Worker// include all file 20*1b3f573fSAndroid Build Coastguard Workerforeach (explode(PATH_SEPARATOR, get_include_path()) as $one_include_path) { 21*1b3f573fSAndroid Build Coastguard Worker _require_all($one_include_path, $one_include_path); 22*1b3f573fSAndroid Build Coastguard Worker} 23*1b3f573fSAndroid Build Coastguard Worker 24*1b3f573fSAndroid Build Coastguard Workeruse Benchmarks\BenchmarkDataset; 25*1b3f573fSAndroid Build Coastguard Worker 26*1b3f573fSAndroid Build Coastguard Workerclass BenchmarkMethod 27*1b3f573fSAndroid Build Coastguard Worker{ 28*1b3f573fSAndroid Build Coastguard Worker // $args[0]: dataset 29*1b3f573fSAndroid Build Coastguard Worker // $args[1]: message class 30*1b3f573fSAndroid Build Coastguard Worker static function parse(&$args) { 31*1b3f573fSAndroid Build Coastguard Worker $payloads = $args[0]->getPayload(); 32*1b3f573fSAndroid Build Coastguard Worker for ($i = $payloads->count() - 1; $i >= 0; $i--) { 33*1b3f573fSAndroid Build Coastguard Worker (new $args[1]())->mergeFromString($payloads->offsetGet($i)); 34*1b3f573fSAndroid Build Coastguard Worker } 35*1b3f573fSAndroid Build Coastguard Worker } 36*1b3f573fSAndroid Build Coastguard Worker 37*1b3f573fSAndroid Build Coastguard Worker // $args: array of message 38*1b3f573fSAndroid Build Coastguard Worker static function serialize(&$args) { 39*1b3f573fSAndroid Build Coastguard Worker foreach ($args as &$temp_message) { 40*1b3f573fSAndroid Build Coastguard Worker $temp_message->serializeToString(); 41*1b3f573fSAndroid Build Coastguard Worker } 42*1b3f573fSAndroid Build Coastguard Worker } 43*1b3f573fSAndroid Build Coastguard Worker} 44*1b3f573fSAndroid Build Coastguard Worker 45*1b3f573fSAndroid Build Coastguard Workerclass Benchmark 46*1b3f573fSAndroid Build Coastguard Worker{ 47*1b3f573fSAndroid Build Coastguard Worker private $benchmark_name; 48*1b3f573fSAndroid Build Coastguard Worker private $args; 49*1b3f573fSAndroid Build Coastguard Worker private $benchmark_time; 50*1b3f573fSAndroid Build Coastguard Worker private $total_bytes; 51*1b3f573fSAndroid Build Coastguard Worker private $coefficient; 52*1b3f573fSAndroid Build Coastguard Worker 53*1b3f573fSAndroid Build Coastguard Worker public function __construct($benchmark_name, $args, $total_bytes, 54*1b3f573fSAndroid Build Coastguard Worker $benchmark_time = 5.0) { 55*1b3f573fSAndroid Build Coastguard Worker $this->args = $args; 56*1b3f573fSAndroid Build Coastguard Worker $this->benchmark_name = $benchmark_name; 57*1b3f573fSAndroid Build Coastguard Worker $this->benchmark_time = $benchmark_time; 58*1b3f573fSAndroid Build Coastguard Worker $this->total_bytes = $total_bytes; 59*1b3f573fSAndroid Build Coastguard Worker $this->coefficient = pow (10, 0) / pow(2, 20); 60*1b3f573fSAndroid Build Coastguard Worker } 61*1b3f573fSAndroid Build Coastguard Worker 62*1b3f573fSAndroid Build Coastguard Worker public function runBenchmark() { 63*1b3f573fSAndroid Build Coastguard Worker $t = $this->runBenchmarkWithTimes(1); 64*1b3f573fSAndroid Build Coastguard Worker $times = ceil($this->benchmark_time / $t); 65*1b3f573fSAndroid Build Coastguard Worker return $this->total_bytes * $times / 66*1b3f573fSAndroid Build Coastguard Worker ($times == 1 ? $t : $this->runBenchmarkWithTimes($times)) * 67*1b3f573fSAndroid Build Coastguard Worker $this->coefficient; 68*1b3f573fSAndroid Build Coastguard Worker } 69*1b3f573fSAndroid Build Coastguard Worker 70*1b3f573fSAndroid Build Coastguard Worker private function runBenchmarkWithTimes($times) { 71*1b3f573fSAndroid Build Coastguard Worker $st = microtime(true); 72*1b3f573fSAndroid Build Coastguard Worker for ($i = 0; $i < $times; $i++) { 73*1b3f573fSAndroid Build Coastguard Worker call_user_func_array($this->benchmark_name, array(&$this->args)); 74*1b3f573fSAndroid Build Coastguard Worker } 75*1b3f573fSAndroid Build Coastguard Worker $en = microtime(true); 76*1b3f573fSAndroid Build Coastguard Worker return $en - $st; 77*1b3f573fSAndroid Build Coastguard Worker } 78*1b3f573fSAndroid Build Coastguard Worker} 79*1b3f573fSAndroid Build Coastguard Worker 80*1b3f573fSAndroid Build Coastguard Workerfunction getMessageName(&$dataset) { 81*1b3f573fSAndroid Build Coastguard Worker switch ($dataset->getMessageName()) { 82*1b3f573fSAndroid Build Coastguard Worker case "benchmarks.proto3.GoogleMessage1": 83*1b3f573fSAndroid Build Coastguard Worker return "\Benchmarks\Proto3\GoogleMessage1"; 84*1b3f573fSAndroid Build Coastguard Worker case "benchmarks.proto2.GoogleMessage1": 85*1b3f573fSAndroid Build Coastguard Worker return "\Benchmarks\Proto2\GoogleMessage1"; 86*1b3f573fSAndroid Build Coastguard Worker case "benchmarks.proto2.GoogleMessage2": 87*1b3f573fSAndroid Build Coastguard Worker return "\Benchmarks\Proto2\GoogleMessage2"; 88*1b3f573fSAndroid Build Coastguard Worker case "benchmarks.google_message3.GoogleMessage3": 89*1b3f573fSAndroid Build Coastguard Worker return "\Benchmarks\Google_message3\GoogleMessage3"; 90*1b3f573fSAndroid Build Coastguard Worker case "benchmarks.google_message4.GoogleMessage4": 91*1b3f573fSAndroid Build Coastguard Worker return "\Benchmarks\Google_message4\GoogleMessage4"; 92*1b3f573fSAndroid Build Coastguard Worker default: 93*1b3f573fSAndroid Build Coastguard Worker exit("Message " . $dataset->getMessageName() . " not found !"); 94*1b3f573fSAndroid Build Coastguard Worker } 95*1b3f573fSAndroid Build Coastguard Worker} 96*1b3f573fSAndroid Build Coastguard Worker 97*1b3f573fSAndroid Build Coastguard Workerfunction runBenchmark($file, $behavior_prefix) { 98*1b3f573fSAndroid Build Coastguard Worker $datafile = fopen($file, "r") or die("Unable to open file " . $file); 99*1b3f573fSAndroid Build Coastguard Worker $bytes = fread($datafile, filesize($file)); 100*1b3f573fSAndroid Build Coastguard Worker $dataset = new BenchmarkDataset(NULL); 101*1b3f573fSAndroid Build Coastguard Worker $dataset->mergeFromString($bytes); 102*1b3f573fSAndroid Build Coastguard Worker $message_name = getMessageName($dataset); 103*1b3f573fSAndroid Build Coastguard Worker $message_list = array(); 104*1b3f573fSAndroid Build Coastguard Worker $total_bytes = 0; 105*1b3f573fSAndroid Build Coastguard Worker $payloads = $dataset->getPayload(); 106*1b3f573fSAndroid Build Coastguard Worker for ($i = $payloads->count() - 1; $i >= 0; $i--) { 107*1b3f573fSAndroid Build Coastguard Worker $new_message = new $message_name(); 108*1b3f573fSAndroid Build Coastguard Worker $new_message->mergeFromString($payloads->offsetGet($i)); 109*1b3f573fSAndroid Build Coastguard Worker array_push($message_list, $new_message); 110*1b3f573fSAndroid Build Coastguard Worker $total_bytes += strlen($payloads->offsetGet($i)); 111*1b3f573fSAndroid Build Coastguard Worker } 112*1b3f573fSAndroid Build Coastguard Worker 113*1b3f573fSAndroid Build Coastguard Worker $parse_benchmark = new Benchmark( 114*1b3f573fSAndroid Build Coastguard Worker "\Google\Protobuf\Benchmark\BenchmarkMethod::parse", 115*1b3f573fSAndroid Build Coastguard Worker array($dataset, $message_name), $total_bytes); 116*1b3f573fSAndroid Build Coastguard Worker $serialize_benchmark = new Benchmark( 117*1b3f573fSAndroid Build Coastguard Worker "\Google\Protobuf\Benchmark\BenchmarkMethod::serialize", 118*1b3f573fSAndroid Build Coastguard Worker $message_list, $total_bytes); 119*1b3f573fSAndroid Build Coastguard Worker 120*1b3f573fSAndroid Build Coastguard Worker return array( 121*1b3f573fSAndroid Build Coastguard Worker "filename" => $file, 122*1b3f573fSAndroid Build Coastguard Worker "benchmarks" => array( 123*1b3f573fSAndroid Build Coastguard Worker $behavior_prefix . "_parse" => $parse_benchmark->runBenchmark(), 124*1b3f573fSAndroid Build Coastguard Worker $behavior_prefix . "_serailize" => $serialize_benchmark->runBenchmark() 125*1b3f573fSAndroid Build Coastguard Worker ), 126*1b3f573fSAndroid Build Coastguard Worker "message_name" => $dataset->getMessageName() 127*1b3f573fSAndroid Build Coastguard Worker ); 128*1b3f573fSAndroid Build Coastguard Worker} 129*1b3f573fSAndroid Build Coastguard Worker 130*1b3f573fSAndroid Build Coastguard Worker// main 131*1b3f573fSAndroid Build Coastguard Worker$json_output = false; 132*1b3f573fSAndroid Build Coastguard Worker$results = array(); 133*1b3f573fSAndroid Build Coastguard Worker$behavior_prefix = ""; 134*1b3f573fSAndroid Build Coastguard Worker 135*1b3f573fSAndroid Build Coastguard Workerforeach ($argv as $index => $arg) { 136*1b3f573fSAndroid Build Coastguard Worker if ($index == 0) { 137*1b3f573fSAndroid Build Coastguard Worker continue; 138*1b3f573fSAndroid Build Coastguard Worker } 139*1b3f573fSAndroid Build Coastguard Worker if ($arg == "--json") { 140*1b3f573fSAndroid Build Coastguard Worker $json_output = true; 141*1b3f573fSAndroid Build Coastguard Worker } else if (strpos($arg, "--behavior_prefix") == 0) { 142*1b3f573fSAndroid Build Coastguard Worker $behavior_prefix = str_replace("--behavior_prefix=", "", $arg); 143*1b3f573fSAndroid Build Coastguard Worker } 144*1b3f573fSAndroid Build Coastguard Worker} 145*1b3f573fSAndroid Build Coastguard Worker 146*1b3f573fSAndroid Build Coastguard Workerforeach ($argv as $index => $arg) { 147*1b3f573fSAndroid Build Coastguard Worker if ($index == 0) { 148*1b3f573fSAndroid Build Coastguard Worker continue; 149*1b3f573fSAndroid Build Coastguard Worker } 150*1b3f573fSAndroid Build Coastguard Worker if (substr($arg, 0, 2) == "--") { 151*1b3f573fSAndroid Build Coastguard Worker continue; 152*1b3f573fSAndroid Build Coastguard Worker } else { 153*1b3f573fSAndroid Build Coastguard Worker array_push($results, runBenchmark($arg, $behavior_prefix)); 154*1b3f573fSAndroid Build Coastguard Worker } 155*1b3f573fSAndroid Build Coastguard Worker} 156*1b3f573fSAndroid Build Coastguard Worker 157*1b3f573fSAndroid Build Coastguard Workerif ($json_output) { 158*1b3f573fSAndroid Build Coastguard Worker print json_encode($results); 159*1b3f573fSAndroid Build Coastguard Worker} else { 160*1b3f573fSAndroid Build Coastguard Worker print "PHP protobuf benchmark result:\n\n"; 161*1b3f573fSAndroid Build Coastguard Worker foreach ($results as $result) { 162*1b3f573fSAndroid Build Coastguard Worker printf("result for test data file: %s\n", $result["filename"]); 163*1b3f573fSAndroid Build Coastguard Worker foreach ($result["benchmarks"] as $benchmark => $throughput) { 164*1b3f573fSAndroid Build Coastguard Worker printf(" Throughput for benchmark %s: %.2f MB/s\n", 165*1b3f573fSAndroid Build Coastguard Worker $benchmark, $throughput); 166*1b3f573fSAndroid Build Coastguard Worker } 167*1b3f573fSAndroid Build Coastguard Worker } 168*1b3f573fSAndroid Build Coastguard Worker} 169*1b3f573fSAndroid Build Coastguard Worker 170*1b3f573fSAndroid Build Coastguard Worker?> 171