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