|
<?php |
|
|
|
/* |
|
* Copyright (c) 2012 Jeremy Perret |
|
* |
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
|
* of this software and associated documentation files (the "Software"), to deal |
|
* in the Software without restriction, including without limitation the rights |
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
* copies of the Software, and to permit persons to whom the Software is furnished |
|
* to do so, subject to the following conditions: |
|
* |
|
* The above copyright notice and this permission notice shall be included in all |
|
* copies or substantial portions of the Software. |
|
* |
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
* THE SOFTWARE. |
|
*/ |
|
|
|
class Ubench |
|
{ |
|
protected $start_time; |
|
|
|
protected $end_time; |
|
|
|
protected $memory_usage; |
|
|
|
/** |
|
* Sets start microtime |
|
* |
|
* @return void |
|
*/ |
|
public function start() |
|
{ |
|
$this->start_time = microtime(true); |
|
} |
|
|
|
/** |
|
* Sets end microtime |
|
* |
|
* @return void |
|
*/ |
|
public function end() |
|
{ |
|
$this->end_time = microtime(true); |
|
$this->memory_usage = memory_get_usage(true); |
|
} |
|
|
|
/** |
|
* Returns the elapsed time, readable or not |
|
* |
|
* @param boolean $readable Whether the result must be human readable |
|
* @param string $format The format to display (printf format) |
|
* @return string|float |
|
*/ |
|
public function getTime($raw = false, $format = null) |
|
{ |
|
$elapsed = $this->end_time - $this->start_time; |
|
|
|
return $raw ? $elapsed : self::readableElapsedTime($elapsed, $format); |
|
} |
|
|
|
/** |
|
* Returns the memory usage at the end checkpoint |
|
* |
|
* @param boolean $readable Whether the result must be human readable |
|
* @param string $format The format to display (printf format) |
|
* @return string|float |
|
*/ |
|
public function getMemoryUsage($raw = false, $format = null) |
|
{ |
|
return $raw ? $this->memory_usage : self::readableSize($this->memory_usage, $format); |
|
} |
|
|
|
/** |
|
* Returns the memory peak, readable or not |
|
* |
|
* @param boolean $readable Whether the result must be human readable |
|
* @param string $format The format to display (printf format) |
|
* @return string|float |
|
*/ |
|
public function getMemoryPeak($raw = false, $format = null) |
|
{ |
|
$memory = memory_get_peak_usage(true); |
|
|
|
return $raw ? $memory : self::readableSize($memory, $format); |
|
} |
|
|
|
/** |
|
* Wraps a callable with start() and end() calls |
|
* |
|
* Additional arguments passed to this method will be passed to |
|
* the callable. |
|
* |
|
* @param callable $callable |
|
* @return mixed |
|
*/ |
|
public function run(callable $callable) |
|
{ |
|
$arguments = func_get_args(); |
|
array_shift($arguments); |
|
|
|
$this->start(); |
|
$result = call_user_func_array($callable, $arguments); |
|
$this->end(); |
|
|
|
return $result; |
|
} |
|
|
|
/** |
|
* Returns a human readable memory size |
|
* |
|
* @param int $size |
|
* @param string $format The format to display (printf format) |
|
* @param int $round |
|
* @return string |
|
*/ |
|
public static function readableSize($size, $format = null, $round = 3) |
|
{ |
|
$mod = 1024; |
|
|
|
if (is_null($format)) { |
|
$format = '%.2f%s'; |
|
} |
|
|
|
$units = explode(' ','B Kb Mb Gb Tb'); |
|
|
|
for ($i = 0; $size > $mod; $i++) { |
|
$size /= $mod; |
|
} |
|
|
|
if (0 === $i) { |
|
$format = preg_replace('/(%.[\d]+f)/', '%d', $format); |
|
} |
|
|
|
return sprintf($format, round($size, $round), $units[$i]); |
|
} |
|
|
|
/** |
|
* Returns a human readable elapsed time |
|
* |
|
* @param float $microtime |
|
* @param string $format The format to display (printf format) |
|
* @return string |
|
*/ |
|
public static function readableElapsedTime($microtime, $format = null, $round = 3) |
|
{ |
|
if (is_null($format)) { |
|
$format = '%.3f%s'; |
|
} |
|
|
|
if ($microtime >= 1) { |
|
$unit = 's'; |
|
$time = round($microtime, $round); |
|
} else { |
|
$unit = 'ms'; |
|
$time = round($microtime*1000); |
|
|
|
$format = preg_replace('/(%.[\d]+f)/', '%d', $format); |
|
} |
|
|
|
return sprintf($format, $time, $unit); |
|
} |
|
} |
|
|
|
function gen_list() { |
|
return range(1, 1000); |
|
} |
|
|
|
function gen_map() { |
|
return ['A' => 0, 'B' => 1, 'C' => 2, 'D' => 3, 'E' => 4, 'F' => 5, 'G' => 6, |
|
'H' => 7, 'I' => 8, 'J' => 9, 'K' => 10, 'L' => 11, 'M' => 12, 'N' => 13, |
|
'O' => 14, 'P' => 15, 'Q' => 16, 'R' => 17, 'S' => 18, 'T' => 19, 'U' => 20, |
|
'V' => 21, 'W' => 22, 'X' => 23, 'Y' => 24, 'Z' => 25]; |
|
} |
|
|
|
function gen_string() { |
|
return file_get_contents('data/UTF-8-demo.txt'); |
|
} |
|
|
|
function gen_data() { |
|
return json_decode(gen_json()); |
|
} |
|
|
|
function gen_json() { |
|
return file_get_contents('data/generated.json'); |
|
} |
|
|
|
function bench_jsond_encode_list() { |
|
echo 'jsond: '; |
|
$data = gen_list(); |
|
$bench = new Ubench; |
|
$bench->run(function ($_data) { |
|
for ($i=0; $i<10000; $i++){ |
|
jsond_encode($_data); |
|
}; |
|
}, $data); |
|
echo microseconds($bench->getTime(true))/10000 . ' μs/op'; |
|
echo PHP_EOL; |
|
} |
|
|
|
function bench_json_encode_list() { |
|
echo 'json: '; |
|
$data = gen_list(); |
|
$bench = new Ubench; |
|
$bench->run(function ($_data) { |
|
for ($i=0; $i<10000; $i++){ |
|
json_encode($_data); |
|
}; |
|
}, $data); |
|
echo microseconds($bench->getTime(true))/10000 . ' μs/op'; |
|
echo PHP_EOL; |
|
} |
|
|
|
function bench_jsond_encode_map() { |
|
echo 'jsond: '; |
|
$data = gen_map(); |
|
$bench = new Ubench; |
|
$bench->run(function ($_data) { |
|
for ($i=0; $i<10000; $i++){ |
|
jsond_encode($_data); |
|
}; |
|
}, $data); |
|
echo microseconds($bench->getTime(true))/10000 . ' μs/op'; |
|
echo PHP_EOL; |
|
} |
|
|
|
function bench_json_encode_map() { |
|
echo 'json: '; |
|
$data = gen_map(); |
|
$bench = new Ubench; |
|
$bench->run(function ($_data) { |
|
for ($i=0; $i<10000; $i++){ |
|
json_encode($_data); |
|
}; |
|
}, $data); |
|
echo microseconds($bench->getTime(true))/10000 . ' μs/op'; |
|
echo PHP_EOL; |
|
} |
|
|
|
function bench_jsond_encode_string() { |
|
echo 'jsond: '; |
|
$data = gen_string(); |
|
$bench = new Ubench; |
|
$bench->run(function ($_data) { |
|
for ($i=0; $i<10000; $i++){ |
|
jsond_encode($_data); |
|
}; |
|
}, $data); |
|
echo microseconds($bench->getTime(true))/10000 . ' μs/op'; |
|
echo PHP_EOL; |
|
} |
|
|
|
function bench_json_encode_string() { |
|
echo 'json: '; |
|
$data = gen_string(); |
|
$bench = new Ubench; |
|
$bench->run(function ($_data) { |
|
for ($i=0; $i<10000; $i++){ |
|
json_encode($_data); |
|
}; |
|
}, $data); |
|
echo microseconds($bench->getTime(true))/10000 . ' μs/op'; |
|
echo PHP_EOL; |
|
} |
|
|
|
function bench_jsond_encode_data() { |
|
echo 'jsond: '; |
|
$data = gen_data(); |
|
$bench = new Ubench; |
|
$bench->run(function ($_data) { |
|
for ($i=0; $i<10000; $i++){ |
|
jsond_encode($_data); |
|
}; |
|
}, $data); |
|
echo microseconds($bench->getTime(true))/10000 . ' μs/op'; |
|
echo PHP_EOL; |
|
} |
|
|
|
function bench_json_encode_data() { |
|
echo 'json: '; |
|
$data = gen_data(); |
|
$bench = new Ubench; |
|
$bench->run(function ($_data) { |
|
for ($i=0; $i<10000; $i++){ |
|
json_encode($_data); |
|
}; |
|
}, $data); |
|
echo microseconds($bench->getTime(true))/10000 . ' μs/op'; |
|
echo PHP_EOL; |
|
} |
|
|
|
function bench_jsond_decode() { |
|
echo 'jsond: '; |
|
$json = gen_json(); |
|
$bench = new Ubench; |
|
$bench->run(function ($_json) { |
|
for ($i=0; $i<10000; $i++){ |
|
jsond_decode($_json); |
|
}; |
|
}, $json); |
|
echo microseconds($bench->getTime(true))/10000 . ' μs/op'; |
|
echo PHP_EOL; |
|
} |
|
|
|
function bench_json_decode() { |
|
echo 'json: '; |
|
$json = gen_json(); |
|
$bench = new Ubench; |
|
$bench->run(function ($_json) { |
|
for ($i=0; $i<10000; $i++){ |
|
json_decode($_json); |
|
}; |
|
}, $json); |
|
echo microseconds($bench->getTime(true))/10000 . ' μs/op'; |
|
echo PHP_EOL; |
|
} |
|
|
|
function microseconds($microtime) { |
|
return $microtime * 1000 * 1000; |
|
} |
|
|
|
function main() { |
|
echo '## EncoderBench' . PHP_EOL . PHP_EOL; |
|
bench_jsond_encode_data(); |
|
bench_json_encode_data(); |
|
echo PHP_EOL; |
|
|
|
echo '## EncoderBench - lists' . PHP_EOL . PHP_EOL; |
|
bench_jsond_encode_list(); |
|
bench_json_encode_list(); |
|
echo PHP_EOL; |
|
|
|
echo '## EncoderBench - maps' . PHP_EOL . PHP_EOL; |
|
bench_jsond_encode_map(); |
|
bench_json_encode_map(); |
|
echo PHP_EOL; |
|
|
|
echo '## EncoderBench - strings' . PHP_EOL . PHP_EOL; |
|
bench_jsond_encode_string(); |
|
bench_json_encode_string(); |
|
echo PHP_EOL; |
|
|
|
echo '## ParserBench' . PHP_EOL . PHP_EOL; |
|
bench_jsond_decode(); |
|
bench_json_decode(); |
|
echo PHP_EOL; |
|
} |
|
|
|
main(); |