PhpBenchmark.php 4.8 KB

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