adsr / phpspy

low-overhead sampling profiler for PHP 7+

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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 [];
    }
commented

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.

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.

  1. The flamegraph with the original getExplicitKeys (total time 12.179 seconds; 38% of samples are getExplicitKeys):
    profile-1.zip
    image
  2. 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
    image

Numbers doesn't match, does they?

commented

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.

[0] https://i.imgur.com/6V5uSf8.png