nette / tracy

😎 Tracy: the addictive tool to ease debugging PHP code for cool developers. Friendly design, logging, profiler, advanced features like debugging AJAX calls or CLI support. You will love it.
https://tracy.nette.org
Other
1.76k stars 218 forks source link

Debugger reserved str_repeat() can be too slow #493

Closed janbarasek closed 3 years ago

janbarasek commented 3 years ago

Hello,

In some cases, evaluating the str_repeat() function for reserved memory can be relatively slow and take up to tens of milliseconds.

https://github.com/nette/tracy/blob/b23da41363546aa750d9f698f21e14815bd78913/src/Tracy/Debugger/Debugger.php#L163

Runtime example from the profiler:

Screenshot from 2021-06-08 09-49-28

Test script:

\Tracy\Debugger::timer('repeat');
for($i=1;$i<=10;$i++) {
    $a = str_repeat('t', 500000*$i);
    dump([
        $i,
        strlen($a),
        \Tracy\Debugger::timer('repeat') * 1000
    ]);
}

Profiler results:

Screenshot from 2021-06-08 09-49-54

Now I don't know how to save time effectively. This problem bothers me, because in some cases it slows down the processing of all requests.

Thanks.

jakubvojacek commented 3 years ago

I've noticed the same in blackfire but never really thought about it since thats in vendor and not my code. Nevertheless, it'd be nice to speed it up :)

janbarasek commented 3 years ago

I analyzed the problem and the reason for the slowdown is that PHP has to dynamically expand the memory used when storing a long string in a variable.

One of the possible solutions is to fill the variable directly, for example:

/** @var string|null reserved memory; also prevents double rendering */
public static $reserved = 'tttt....';

Or fill the memory in another way and not use the variable.

dg commented 3 years ago

That's the price of memory allocation, and there's no way to speed it up.

JanTvrdik commented 3 years ago

The str_repeat function with single byte string is heavily optimized in php-engine to a single memset call. https://github.com/php/php-src/blob/php-8.0.7/ext/standard/string.c#L5184

@janbarasek You can always set $reservedMemorySize to zero if you wanto effectively disable this feature.