commit
d2980062c8
4 changed files with 263 additions and 3 deletions
@ -0,0 +1,157 @@ |
||||
<?php |
||||
|
||||
namespace Google\Protobuf\Benchmark; |
||||
|
||||
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 / |
||||
$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) { |
||||
$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( |
||||
"parse_php" => $parse_benchmark->runBenchmark(), |
||||
"serailize_php" => $serialize_benchmark->runBenchmark() |
||||
), |
||||
"message_name" => $dataset->getMessageName() |
||||
); |
||||
} |
||||
|
||||
// main |
||||
$json_output = false; |
||||
$results = array(); |
||||
foreach ($argv as $index => $arg) { |
||||
if ($index == 0) { |
||||
continue; |
||||
} |
||||
if ($arg == "--json") { |
||||
$json_output = true; |
||||
continue; |
||||
} else { |
||||
array_push($results, runBenchmark($arg)); |
||||
} |
||||
} |
||||
|
||||
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); |
||||
} |
||||
} |
||||
} |
||||
|
||||
?> |
@ -0,0 +1,25 @@ |
||||
<?php |
||||
|
||||
define("GOOGLE_INTERNAL_NAMESPACE", "Google\\Protobuf\\Internal\\"); |
||||
define("GOOGLE_NAMESPACE", "Google\\Protobuf\\"); |
||||
define("GOOGLE_GPBMETADATA_NAMESPACE", "GPBMetadata\\Google\\Protobuf\\"); |
||||
define("BENCHMARK_NAMESPACE", "Benchmarks"); |
||||
define("BENCHMARK_GPBMETADATA_NAMESPACE", "GPBMetadata\\Benchmarks"); |
||||
|
||||
function protobuf_autoloader_impl($class, $prefix, $include_path) { |
||||
$length = strlen($prefix); |
||||
if ((substr($class, 0, $length) === $prefix)) { |
||||
$path = $include_path . '/' . implode('/', array_map('ucwords', explode('\\', $class))) . '.php'; |
||||
include_once $path; |
||||
} |
||||
} |
||||
|
||||
function protobuf_autoloader($class) { |
||||
protobuf_autoloader_impl($class, GOOGLE_INTERNAL_NAMESPACE, getenv('PROTOBUF_PHP_SRCDIR')); |
||||
protobuf_autoloader_impl($class, GOOGLE_NAMESPACE, getenv('PROTOBUF_PHP_SRCDIR')); |
||||
protobuf_autoloader_impl($class, GOOGLE_GPBMETADATA_NAMESPACE, getenv('PROTOBUF_PHP_SRCDIR')); |
||||
protobuf_autoloader_impl($class, BENCHMARK_NAMESPACE, getenv('CURRENT_DIR')); |
||||
protobuf_autoloader_impl($class, BENCHMARK_GPBMETADATA_NAMESPACE, getenv('CURRENT_DIR')); |
||||
} |
||||
|
||||
spl_autoload_register('protobuf_autoloader'); |
Loading…
Reference in new issue