Skip to content

Commit 9b85c9d

Browse files
committed
Another 7-8% of performance improvement by caching peek() data
Cache the common case of a single byte of peek data.
1 parent f25d7aa commit 9b85c9d

File tree

1 file changed

+20
-3
lines changed

1 file changed

+20
-3
lines changed

lib/Sabberworm/CSS/Parser.php

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class Parser {
3131
private $oParserSettings;
3232
private $sCharset;
3333
private $iLength;
34+
private $peekCache = null;
3435

3536
public function __construct($sText, Settings $oParserSettings = null) {
3637
$this->sText = $sText;
@@ -268,6 +269,7 @@ private function parseRuleSet($oRuleSet) {
268269
// We need to “unfind” the matches to the end of the ruleSet as this will be matched later
269270
if($this->streql($this->substr($sConsume, $this->strlen($sConsume)-1, 1), '}')) {
270271
--$this->iCurrentPosition;
272+
$this->peekCache = null;
271273
} else {
272274
$this->consumeWhiteSpace();
273275
while ($this->comes(';')) {
@@ -446,7 +448,7 @@ private function parseURLValue() {
446448
}
447449
return $oResult;
448450
}
449-
451+
450452
/**
451453
* Tests an identifier for a given value. Since identifiers are all keywords, they can be vendor-prefixed. We need to check for these versions too.
452454
*/
@@ -468,12 +470,25 @@ private function peek($iLength = 1, $iOffset = 0) {
468470
if (is_string($iOffset)) {
469471
$iOffset = $this->strlen($iOffset);
470472
}
471-
$iOffset = $this->iCurrentPosition + $iOffset;
473+
if (($peek = (!$iOffset && ($iLength == 1))) &&
474+
!is_null($this->peekCache)) {
475+
return $this->peekCache;
476+
}
477+
if (!is_null($this->peekCache) &&
478+
$iLength == 1 &&
479+
$iOffset = 0) {
480+
return $this->peekCache;
481+
}
482+
$iOffset += $this->iCurrentPosition;
472483
if ($iOffset >= $this->iLength) {
473484
return '';
474485
}
475486
$iLength = min($iLength, $this->iLength-$iOffset);
476-
return $this->substr($this->sText, $iOffset, $iLength);
487+
$out = $this->substr($this->sText, $iOffset, $iLength);
488+
if ($peek) {
489+
$this->peekCache = $out;
490+
}
491+
return $out;
477492
}
478493

479494
private function consume($mValue = 1) {
@@ -483,13 +498,15 @@ private function consume($mValue = 1) {
483498
throw new UnexpectedTokenException($mValue, $this->peek(max($iLength, 5)));
484499
}
485500
$this->iCurrentPosition += $this->strlen($mValue);
501+
$this->peekCache = null;
486502
return $mValue;
487503
} else {
488504
if ($this->iCurrentPosition + $mValue > $this->iLength) {
489505
throw new UnexpectedTokenException($mValue, $this->peek(5), 'count');
490506
}
491507
$sResult = $this->substr($this->sText, $this->iCurrentPosition, $mValue);
492508
$this->iCurrentPosition += $mValue;
509+
$this->peekCache = null;
493510
return $sResult;
494511
}
495512
}

0 commit comments

Comments
 (0)