Protocol Buffers - Google's data interchange format (grpc依赖)
https://developers.google.com/protocol-buffers/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
171 lines
5.1 KiB
171 lines
5.1 KiB
5 years ago
|
<?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);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
?>
|