Skip to content

Instantly share code, notes, and snippets.

@vbarinov
Created March 29, 2017 09:42
Show Gist options
  • Save vbarinov/e614d73d68e1a9ab8f1b60a4c232a842 to your computer and use it in GitHub Desktop.
Save vbarinov/e614d73d68e1a9ab8f1b60a4c232a842 to your computer and use it in GitHub Desktop.
Parse ini-style configuration with compound keys in PHP. Cycle vs recursion
<?php
// Recursion splitting: 0.0020239353179932 sec
// Cycle splitting: 0.001431941986084 sec
// Recursion splitting: 0.000885009765625 sec
// Cycle splitting: 0.00057697296142578 sec
$i = <<<INI
db.user.name = vasya
db.user.password = asd123
db.user.type.geo.x = 0
db.user.type.geo.y = 0
db.user.type.geo.db.user.type.geo.db.user.type.geo.db.user.type.geo.db.user.type.geo.db.user.type.geo.y = ok
db.type = postgresql
INI;
$parsedArr = parse_ini_string($i);
// recursion
$splittedArrRec = [];
benchmark();
foreach ($parsedArr as $k => $v) {
splitterRec($k, $v, $splittedArrRec);
}
benchmark('true', 'Recursion splitting: ');
function splitterRec($key, $val, array &$arr) {
if (strpos($key, '.') !== false) {
$pieces = explode('.', $key, 2);
if (!isset($arr[$pieces[0]])) {
$arr[$pieces[0]] = [];
}
splitterRec($pieces[1], $val, $arr[$pieces[0]]);
} else {
$arr[$key] = $val;
}
}
// w/o recursion
benchmark();
splitter($parsedArr);
benchmark(true, 'Cycle splitting: ');
function splitter(array $arr) {
$splitted = [];
foreach ($arr as $k => $v) {
$x = &$splitted;
$pieces = explode('.', $k);
while (count($pieces) > 1) {
$piece = array_shift($pieces);
if (!isset($x[$piece])) $x[$piece] = [];
$x = &$x[$piece];
}
$x[$pieces[0]] = $v;
}
return $splitted;
}
function benchmark($end = false, $label = '') {
static $before;
if ($end) {
$after = microtime(true);
echo $label . ($after - $before) . " sec\n";
} else {
$before = microtime(true);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment