php - Results of a simple execution time check contradict Xdebug profiling results -
i have expensive method removecolumns(...)
, in addition gets called multiple times. want increase performance. analyze optimization results use 2 tools: (1) xdebug profiler webgrind , (2) simple execution time measuring script (that executed on command line within phpunit test method):
$timestart = microtime(true); ($i=0 ; $i < 1000000; $i++) { // code measure $this->...->removecolumns($testarray, $columnnames, $iswhitelist); } $timestop = microtime(true); $resulttime = $timestop - $timestart; $cycletime = $resulttime / $i; echo number_format($cycletime, 10, ',', '') . ' sec/run'; die(php_eol . '###' . php_eol);
but i'm looking @ results -- , see, results ot both tooas absolutely contrarian each other.
the execution time measuring script's results are:
variant sec/run (x69) sec/run (x1000) sec/run (x10000) sec/run (x100000) 1 0,0000121144 0,0000102139 0,0000092316 0,0000089004 2 0,0000115650 0,0000112779 0,0000098540 0,0000098941 3 0,0000228260 0,0000240171 0,0000250236 0,0000800230 difference ms (1-2) 0,0000005494 -0,0000010640 -0,0000006224 -0,0000009937 yield % (1-2) 4,54% -10,42% -6,74% -11,16% difference ms (1-3) -0,0000107116 -0,0000138032 -0,0000157920 -0,0000711226 yield % (1-3) -88,42% -135,14% -171,06% -799,09%
as can see, optimization failed. when method called not often, performance becomes better, more calls, worse (nonlinear, 900%
performance losses on 100.000
calls).
now let's see xdebug profiler's results:
variant xdp-filename xdp-filesize calls total self (ms) total inclusive (ms) 1 1474536556 445,678 kb 69 77325 77403 2 1474537523 402,208 kb 69 1267 1270 3 1474539908 402,963 kb 69 2443 2455 difference ms (1-2) 76058 76133 yield % (1-2) 98,36% 98,36% difference ms (1-3) 74882 74948 yield % (1-3) 96,84% 96,83%
so here performance of improved variants (2
, 3
) is/seems better, performance of variant 1
.
what wrong here , how fix adequate performance testing results?
all 3 variants of method, i'm optimizing:
variant 1
public function removecolumns(array $table, array $columnnames, bool $iswhitelist = false) { foreach ($table $rowkey => $row) { if (is_array($row)) { foreach ($row $fieldname => $fieldvalue) { $remove = $iswhitelist ? ! in_array($fieldname, $columnnames) : in_array($fieldname, $columnnames) ; if ($remove) { unset($table[$rowkey][$fieldname]); } } } } return $table; }
variant 2
public function removecolumns(array $table, array $columnnames, bool $iswhitelist = false) { $tablekeys = array_keys($table); $firstrowkey = $tablekeys[0]; $firstrow = $table[$firstrowkey]; $allcolumnnames = array_keys($firstrow); $resultcolumns = []; foreach ($allcolumnnames $columnname) { $remain = $iswhitelist ? in_array($columnname, $columnnames) : ! in_array($columnname, $columnnames) ; if($remain) { $resultcolumns[$columnname] = array_column($table, $columnname); } } $index = 0; $resulttable = []; foreach ($resultcolumns $resultcolumnname => $resultcolumn) { foreach ($tablekeys $index => $tablekey) { $resulttable[$tablekey][$resultcolumnname] = $resultcolumn[$index]; } } return $resulttable; }
variant 3
public function removecolumns(array $table, array $columnnames, bool $iswhitelist = false) { $tablekeys = array_keys($table); $firstrowkey = $tablekeys[0]; $firstrow = $table[$firstrowkey]; $allcolumnnames = array_keys($firstrow); $columns = []; $i = 0; $arraymapinputvarnames = []; foreach ($allcolumnnames $columnname) { $remain = ($iswhitelist && in_array($columnname, $columnnames)) || (! $iswhitelist && ! in_array($columnname, $columnnames)) ; if($remain) { $varname = 'column' . $i++; $$varname = $columns[$columnname] = array_column($table, $columnname); $arraymapinputvarnames[] = '$' . $varname; } } $arraymapinputstring = implode(', ', $arraymapinputvarnames); eval('$rows = array_map(null, ' . $arraymapinputstring . ');'); foreach ($rows $index => $row) { $rows[$index] = array_combine(array_keys($columns), array_values($row)); } $table = array_combine(array_keys($table), $rows); return $table; }
is function intended do?
<?php $table=array( 'col1'=>'val1', 'col2'=>'val2', 'col3'=>'val3', 'col4'=>'val4' ); $columnnames=array( 'col2','col3' ); function removecolumns($table, $columnnames, $iswhitelist = false) { if ($iswhitelist) return array_intersect_key($table,array_flip($columnnames)); return array_diff_key($table,array_flip($columnnames)); } print 'blacklist:'.var_export(removecolumns($table,$columnnames,false),1).php_eol; print 'whitelist:'.var_export(removecolumns($table,$columnnames,true),1).php_eol;
output:
blacklist:array ( 'col1' => 'val1', 'col4' => 'val4', ) whitelist:array ( 'col2' => 'val2', 'col3' => 'val3', )
but did not measured performance. upload xdebug output of code somewhere?
Comments
Post a Comment