| <?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); | |
| } | |
| } | |
| } | |
| ?> |