annotate vendor/nikic/php-parser/doc/component/Performance.markdown @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 5fb285c0d0e3
children
rev   line source
Chris@13 1 Performance
Chris@13 2 ===========
Chris@13 3
Chris@13 4 Parsing is computationally expensive task, to which the PHP language is not very well suited.
Chris@13 5 Nonetheless, there are a few things you can do to improve the performance of this library, which are
Chris@13 6 described in the following.
Chris@13 7
Chris@13 8 Xdebug
Chris@13 9 ------
Chris@13 10
Chris@13 11 Running PHP with XDebug adds a lot of overhead, especially for code that performs many method calls.
Chris@13 12 Just by loading XDebug (without enabling profiling or other more intrusive XDebug features), you
Chris@13 13 can expect that code using PHP-Parser will be approximately *five times slower*.
Chris@13 14
Chris@13 15 As such, you should make sure that XDebug is not loaded when using this library. Note that setting
Chris@13 16 the `xdebug.default_enable=0` ini option does *not* disable XDebug. The *only* way to disable
Chris@13 17 XDebug is to not load the extension in the first place.
Chris@13 18
Chris@13 19 If you are building a command-line utility for use by developers (who often have XDebug enabled),
Chris@13 20 you may want to consider automatically restarting PHP with XDebug unloaded. The
Chris@13 21 [composer/xdebug-handler](https://github.com/composer/xdebug-handler) package can be used to do
Chris@13 22 this.
Chris@13 23
Chris@13 24 If you do run with XDebug, you may need to increase the `xdebug.max_nesting_level` option to a
Chris@13 25 higher level, such as 3000. While the parser itself is recursion free, most other code working on
Chris@13 26 the AST uses recursion and will generate an error if the value of this option is too low.
Chris@13 27
Chris@13 28 Assertions
Chris@13 29 ----------
Chris@13 30
Chris@13 31 Assertions should be disabled in a production context by setting `zend.assertions=-1` (or
Chris@13 32 `zend.assertions=0` if set at runtime). The library currently doesn't make heavy use of assertions,
Chris@13 33 but they are used in an increasing number of places.
Chris@13 34
Chris@13 35 Object reuse
Chris@13 36 ------------
Chris@13 37
Chris@13 38 Many objects in this project are designed for reuse. For example, one `Parser` object can be used to
Chris@13 39 parse multiple files.
Chris@13 40
Chris@13 41 When possible, objects should be reused rather than being newly instantiated for every use. Some
Chris@13 42 objects have expensive initialization procedures, which will be unnecessarily repeated if the object
Chris@13 43 is not reused. (Currently two objects with particularly expensive setup are lexers and pretty
Chris@13 44 printers, though the details might change between versions of this library.)
Chris@13 45
Chris@13 46 Garbage collection
Chris@13 47 ------------------
Chris@13 48
Chris@13 49 A limitation in PHP's cyclic garbage collector may lead to major performance degradation when the
Chris@13 50 active working set exceeds 10000 objects (or arrays). Especially when parsing very large files this
Chris@13 51 limit is significantly exceeded and PHP will spend the majority of time performing unnecessary
Chris@13 52 garbage collection attempts.
Chris@13 53
Chris@13 54 Without GC, parsing time is roughly linear in the input size. With GC, this degenerates to quadratic
Chris@13 55 runtime for large files. While the specifics may differ, as a rough guideline you may expect a 2.5x
Chris@13 56 GC overhead for 500KB files and a 5x overhead for 1MB files.
Chris@13 57
Chris@13 58 Because this a limitation in PHP's implementation, there is no easy way to work around this. If
Chris@13 59 possible, you should avoid parsing very large files, as they will impact overall execution time
Chris@13 60 disproportionally (and are usually generated anyway).
Chris@13 61
Chris@13 62 Of course, you can also try to (temporarily) disable GC. By design the AST generated by PHP-Parser
Chris@13 63 is cycle-free, so the AST itself will never cause leaks with GC disabled. However, other code
Chris@13 64 (including for example the parser object itself) may hold cycles, so disabling of GC should be
Chris@13 65 approached with care.