Skip to content

Instantly share code, notes, and snippets.

@Atulin
Last active August 12, 2019 15:57
Show Gist options
  • Save Atulin/99a6f2433aeb7ddcd5332d5248bfc382 to your computer and use it in GitHub Desktop.
Save Atulin/99a6f2433aeb7ddcd5332d5248bfc382 to your computer and use it in GitHub Desktop.
Script benchmarking data read from json, yaml, and plain PHP array
<?php
// Length of each data string in bytes
$LENGTH = $_GET['length'] ?? 10;
// Number of data strings in each last branch
$ELEMENTS = $_GET['elements'] ?? 5;
// Number of sub-branches of each branc and root
$DEPTH = $_GET['depth'] ?? 3;
// How many times to repeat the benchmark
$TRIES = $_GET['tries'] ?? 1;
// If true, geenrates new data files and runs the benchmark
// If false, simply runs the benchmark
$REGEN = $_GET['regen'] ?? false;
$php_data_var_name = 'TESTDATA';
$json_file_path = 'benchmark_cfgs/data-json.json';
$yaml_file_path = 'benchmark_cfgs/data-yaml.yaml';
$php_file_path = 'benchmark_cfgs/data-php.php';
require_once '../vendor/autoload.php';
use Symfony\Component\Yaml\Yaml;
///
/// CREATE RANDOM ELEMENTS
///
function createElements(int $elementCount, int $elementLength): array
{
$out = [];
for ($i = 0; $i < $elementCount; $i++) {
try {
$out[] = bin2hex(random_bytes($elementLength));
} catch (Exception $e) {
$out[] = $e->getMessage();
}
}
return $out;
}
///
/// CREATE TREE BRANCH
///
function nestElements(int $depth, int $elementCount, int $elementLength, array $arr = [], int $currentDepth = 0): array
{
if ($currentDepth >= $depth - 1) {
for ($i = 0; $i < $depth; $i++) {
$arr[] = createElements($elementCount, $elementLength);
}
return $arr;
}
$currentArr = [];
for ($i = 0; $i < $depth; $i++) {
$currentArr[] = nestElements($depth, $elementCount, $elementLength, $arr, $currentDepth + 1);
}
return $currentArr;
}
function minmax($min, $max, $val) {
if ($val === $min) {
return 'min';
}
if ($val === $max) {
return 'max';
}
return '';
}
if($REGEN) {
$res = nestElements($DEPTH, $ELEMENTS, $LENGTH);
// Create data strings
$json = json_encode($res, JSON_PRETTY_PRINT);
$yaml = Yaml::dump($res, 500);
$php = '<?php' . PHP_EOL . "$$php_data_var_name = " . var_export($res, true) . ';';
file_put_contents($json_file_path, $json);
file_put_contents($yaml_file_path, $yaml);
file_put_contents($php_file_path, $php);
}
function TimeRead(string $json_file_path, string $yaml_file_path, string $php_file_path, string $php_data_var_name)
{
// Timing
$time_start_json = microtime(true);
$data_json = json_decode(file_get_contents($json_file_path), true);
$time_end_json = microtime(true);
$time_start_yaml = microtime(true);
$data_yaml = Yaml::parseFile($yaml_file_path);
$time_end_yaml = microtime(true);
$time_start_php = microtime(true);
require $php_file_path;
$data_php = $$php_data_var_name;
$time_end_php = microtime(true);
// Check if data was loaded
$json_loaded = $data_json ? 'Loaded' : 'Failed';
$yaml_loaded = $data_yaml ? 'Loaded' : 'Failed';
$php_loaded = $data_php ? 'Loaded' : 'Failed';
// Calculate load times
$json_time = $time_end_json - $time_start_json;
$yaml_time = $time_end_yaml - $time_start_yaml;
$php_time = $time_end_php - $time_start_php;
$times = [
$json_time,
$yaml_time,
$php_time ,
];
$max_t = max($times);
$min_t = min($times);
// Calculate file size
$json_size = filesize($json_file_path);
$yaml_size = filesize($yaml_file_path);
$php_size = filesize($php_file_path);
$sizes = [
$json_size,
$yaml_size,
$php_size,
];
$max_s = max($sizes);
$min_s = min($sizes);
$html = "<style>
table{border:1px solid black;margin:1rem;border-collapse:collapse}
td{border:1px solid black;padding:.2rem 1rem;}
th{border:1px solid black;padding:.2rem 1rem;font-weight:bold;}
.min{background:#82ff74;}
.max{background:#ff7e7b;}
</style>
<table>
<tr>
<th>Data type</th>
<th>Status</th>
<th>Parse time</th>
<th>File size</th>
</tr>
<tr>
<td>Json</td>
<td>{$json_loaded}</td>
<td class='".minmax($min_t, $max_t, $json_time)."'>{$json_time}</td>
<td class='".minmax($min_s, $max_s, $json_size)."'>{$json_size}</td>
</tr>
<tr>
<td>Yaml</td>
<td>{$yaml_loaded}</td>
<td class='".minmax($min_t, $max_t, $yaml_time)."'>{$yaml_time}</td>
<td class='".minmax($min_s, $max_s, $yaml_size)."'>{$yaml_size}</td>
</tr>
<tr>
<td>PHP</td>
<td>{$php_loaded}</td>
<td class='".minmax($min_t, $max_t, $php_time)."'>{$php_time}</td>
<td class='".minmax($min_s, $max_s, $php_size)."'>{$php_size}</td>
</tr>
</table>";
return $html;
}
// Test read times
for ($i = 0; $i < $TRIES; $i++) {
echo TimeRead($json_file_path, $yaml_file_path, $php_file_path, $php_data_var_name);
}

Results

results

With the below settings:

$LENGTH   = 32
$ELEMENTS = 50
$DEPTH    = 5
$TRIES    = 5

Looks like parsing a Json file is faster than require config.php, which is surprising to say the least.

Also, holy shit, I did not expect symfony/yaml to be this slow comparatively.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment