Wrong stack reported
halaei opened this issue · comments
- PHP version: 7.2.29
- phpspy version: v0.5.0 USE_ZEND=n (commit 58575aa)
Hi there. Is there a chance that the sampling reports wrong stack, especially in presence of calls to prem_match?
I have a function that calls preg_match, str_replace, preg_quate, and array_shift. Flame graph reports that it takes 32% of runtime, of total 10 seconds. However, when I replace the implementation with something simpler that works correct for my input, the flame graph says it takes 1% of runtime, while the total runtime still remains nearly 10 seconds. I know this is somehow a random experiment, but I tried it many times with different sampling rates, with/without opcache. All the same.
Here is the function that I think causes the wrong reports:
protected function getExplicitKeys($attribute)
{
// Uncommenting the next line for my input returns the valid output.
// return [(int) trim($attribute, 'aray.')];
$pattern = str_replace('\*', '([^\.]+)', preg_quote($this->getPrimaryAttribute($attribute), '/'));
if (preg_match('/^'.$pattern.'/', $attribute, $keys)) {
array_shift($keys);
return $keys;
}
return [];
}
Hi @halaei. Can you provide a complete minimal repro example? I don't see anything unusual about these implementations other than they are both probably very fast, so the profiler has to get 'lucky' to see them.
I was profiling Laravel validation with some special inputs. Sorry, I don't know how minimal I can get.
- laravel/framework version: https://github.com/halaei/framework/tree/performace-improvements
- laravel/laravel version: 7.x
- console command: (in routes/console.php)
Artisan::command('profile', function () {
\Illuminate\Support\Facades\Validator::validate([
'array' => range(1, 500000),
], [
'array.*' => 'required|string',
]);
});
This command ./phpspy --buffer-size=40000 --pause-process -H 141 -- php {{laravel root}}/artisan profile
will call getExplicitKeys 1 million times.
- The flamegraph with the original getExplicitKeys (total time 12.179 seconds; 38% of samples are getExplicitKeys):
profile-1.zip
- The flamegraph with adding
return [trim($attribute, 'aray.')];
at the beginning of getExplicitKeys (total time 11.364s; 0.66% of samples are getExplicitKeys).
profile-2.zip
Numbers doesn't match, does they?
Hi. I ran phpspy against the function you pasted with and without the early return. I don't see anything out of the ordinary. The early return one ran faster and represented less samples in the trace as expected[0]. If you can put together a minimal repro setup I'd be happy to take another look.