| <?php |
| |
| namespace Google\Protobuf\Benchmark; |
| ini_set('memory_limit', '4096M'); |
| |
| const NAME = "PhpBenchmark.php"; |
| |
| function _require_all($dir, &$prefix) { |
| // require all php files |
| foreach (glob("$dir/*") as $path) { |
| if (preg_match('/\.php$/', $path) && |
| substr($path, -strlen(NAME)) != NAME) { |
| require_once(substr($path, strlen($prefix) + 1)); |
| } elseif (is_dir($path)) { |
| _require_all($path, $prefix); |
| } |
| } |
| } |
| // include all file |
| foreach (explode(PATH_SEPARATOR, get_include_path()) as $one_include_path) { |
| _require_all($one_include_path, $one_include_path); |
| } |
| |
| use Benchmarks\BenchmarkDataset; |
| |
| class BenchmarkMethod |
| { |
| // $args[0]: dataset |
| // $args[1]: message class |
| static function parse(&$args) { |
| $payloads = $args[0]->getPayload(); |
| for ($i = $payloads->count() - 1; $i >= 0; $i--) { |
| (new $args[1]())->mergeFromString($payloads->offsetGet($i)); |
| } |
| } |
| |
| // $args: array of message |
| static function serialize(&$args) { |
| foreach ($args as &$temp_message) { |
| $temp_message->serializeToString(); |
| } |
| } |
| } |
| |
| class Benchmark |
| { |
| private $benchmark_name; |
| private $args; |
| private $benchmark_time; |
| private $total_bytes; |
| private $coefficient; |
| |
| public function __construct($benchmark_name, $args, $total_bytes, |
| $benchmark_time = 5.0) { |
| $this->args = $args; |
| $this->benchmark_name = $benchmark_name; |
| $this->benchmark_time = $benchmark_time; |
| $this->total_bytes = $total_bytes; |
| $this->coefficient = pow (10, 0) / pow(2, 20); |
| } |
| |
| public function runBenchmark() { |
| $t = $this->runBenchmarkWithTimes(1); |
| $times = ceil($this->benchmark_time / $t); |
| return $this->total_bytes * $times / |
| ($times == 1 ? $t : $this->runBenchmarkWithTimes($times)) * |
| $this->coefficient; |
| } |
| |
| private function runBenchmarkWithTimes($times) { |
| $st = microtime(true); |
| for ($i = 0; $i < $times; $i++) { |
| call_user_func_array($this->benchmark_name, array(&$this->args)); |
| } |
| $en = microtime(true); |
| return $en - $st; |
| } |
| } |
| |
| function getMessageName(&$dataset) { |
| switch ($dataset->getMessageName()) { |
| case "benchmarks.proto3.GoogleMessage1": |
| return "\Benchmarks\Proto3\GoogleMessage1"; |
| case "benchmarks.proto2.GoogleMessage1": |
| return "\Benchmarks\Proto2\GoogleMessage1"; |
| case "benchmarks.proto2.GoogleMessage2": |
| return "\Benchmarks\Proto2\GoogleMessage2"; |
| case "benchmarks.google_message3.GoogleMessage3": |
| return "\Benchmarks\Google_message3\GoogleMessage3"; |
| case "benchmarks.google_message4.GoogleMessage4": |
| return "\Benchmarks\Google_message4\GoogleMessage4"; |
| default: |
| exit("Message " . $dataset->getMessageName() . " not found !"); |
| } |
| } |
| |
| function runBenchmark($file, $behavior_prefix) { |
| $datafile = fopen($file, "r") or die("Unable to open file " . $file); |
| $bytes = fread($datafile, filesize($file)); |
| $dataset = new BenchmarkDataset(NULL); |
| $dataset->mergeFromString($bytes); |
| $message_name = getMessageName($dataset); |
| $message_list = array(); |
| $total_bytes = 0; |
| $payloads = $dataset->getPayload(); |
| for ($i = $payloads->count() - 1; $i >= 0; $i--) { |
| $new_message = new $message_name(); |
| $new_message->mergeFromString($payloads->offsetGet($i)); |
| array_push($message_list, $new_message); |
| $total_bytes += strlen($payloads->offsetGet($i)); |
| } |
| |
| $parse_benchmark = new Benchmark( |
| "\Google\Protobuf\Benchmark\BenchmarkMethod::parse", |
| array($dataset, $message_name), $total_bytes); |
| $serialize_benchmark = new Benchmark( |
| "\Google\Protobuf\Benchmark\BenchmarkMethod::serialize", |
| $message_list, $total_bytes); |
| |
| return array( |
| "filename" => $file, |
| "benchmarks" => array( |
| $behavior_prefix . "_parse" => $parse_benchmark->runBenchmark(), |
| $behavior_prefix . "_serailize" => $serialize_benchmark->runBenchmark() |
| ), |
| "message_name" => $dataset->getMessageName() |
| ); |
| } |
| |
| // main |
| $json_output = false; |
| $results = array(); |
| $behavior_prefix = ""; |
| |
| foreach ($argv as $index => $arg) { |
| if ($index == 0) { |
| continue; |
| } |
| if ($arg == "--json") { |
| $json_output = true; |
| } else if (strpos($arg, "--behavior_prefix") == 0) { |
| $behavior_prefix = str_replace("--behavior_prefix=", "", $arg); |
| } |
| } |
| |
| foreach ($argv as $index => $arg) { |
| if ($index == 0) { |
| continue; |
| } |
| if (substr($arg, 0, 2) == "--") { |
| continue; |
| } else { |
| array_push($results, runBenchmark($arg, $behavior_prefix)); |
| } |
| } |
| |
| if ($json_output) { |
| print json_encode($results); |
| } else { |
| print "PHP protobuf benchmark result:\n\n"; |
| foreach ($results as $result) { |
| printf("result for test data file: %s\n", $result["filename"]); |
| foreach ($result["benchmarks"] as $benchmark => $throughput) { |
| printf(" Throughput for benchmark %s: %.2f MB/s\n", |
| $benchmark, $throughput); |
| } |
| } |
| } |
| |
| ?> |