sabberworm/PHP-CSS-Parser — pull request #68 by slusarz (2013-09-23 05:32:26+00:00)
Title: Drastic performance increases in the CSS parser

Recently we were alerted of extremely slow performance of the CSS parser:

http://lists.horde.org/archives/imp/Week-of-Mon-20130916/055480.html

I couldn't reproduce 40 second runtimes, but there was a definite lag. Running a xdebug() profiler produced an almost 1 GB output, with certain internal CSS parsing functions being called 1,000,000 times(!). And slow functions like substr() and strtolower() were being run 400,000 times each.

Making a quick pass through the parser, the low-hanging fruit was the code dealing with comparisons on a single byte. In almost every case, consume(), peek() and comes() is absolute overkill when scanning for a single byte that is known NOT to be a multibyte token.

Just changing these calls to a much simpler currentByte() (just grabbing the string index at the current position) and consumeByte() (just incrementing the current pointer) slashed the runtime by more than 50%. Rough example: the xdebug trace file dropped from about 968 MB to 436 MB.

The parser should really be rewritten into a stream parser/tokenizer to achieve maximum speed, but this at least is a good start for very simple changes.