PhpBenchmark.php 5.1 KB

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