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