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