Created
March 29, 2017 09:42
-
-
Save vbarinov/e614d73d68e1a9ab8f1b60a4c232a842 to your computer and use it in GitHub Desktop.
Parse ini-style configuration with compound keys in PHP. Cycle vs recursion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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