Skip to content

Commit 782a9ab

Browse files
committed
Improve performance
I have identified three main bottlenecks when profiling the code with xdebug: 1. `array_shift()`: The array of tokens ended up being renumbered on each iteration. So we instead set consumed tokens to `null`. 2. `mb_substr()`: Using mutltibyte here is unnecessary and overkill, when we can just operate directly on the string. 3. `Liquid::get()`: This one surprised me, but due to the number of calls, here it is. Shave off more processing time by accessing the config array directly.
1 parent de705d5 commit 782a9ab

File tree

2 files changed

+18
-10
lines changed

2 files changed

+18
-10
lines changed

src/Liquid/AbstractBlock.php

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,20 @@ public function getNodelist()
5151
*/
5252
public function parse(array &$tokens)
5353
{
54-
$startRegexp = new Regexp('/^' . Liquid::get('TAG_START') . '/');
55-
$tagRegexp = new Regexp('/^' . Liquid::get('TAG_START') . Liquid::get('WHITESPACE_CONTROL') . '?\s*(\w+)\s*(.*?)' . Liquid::get('WHITESPACE_CONTROL') . '?' . Liquid::get('TAG_END') . '$/s');
56-
$variableStartRegexp = new Regexp('/^' . Liquid::get('VARIABLE_START') . '/');
54+
$startRegexp = new Regexp('/^' . Liquid::$config['TAG_START'] . '/');
55+
$tagRegexp = new Regexp('/^' . Liquid::$config['TAG_START'] . Liquid::$config['WHITESPACE_CONTROL'] . '?\s*(\w+)\s*(.*?)' . Liquid::$config['WHITESPACE_CONTROL'] . '?' . Liquid::$config['TAG_END'] . '$/s');
56+
$variableStartRegexp = new Regexp('/^' . Liquid::$config['VARIABLE_START'] . '/');
5757

5858
$this->nodelist = array();
5959

6060
$tags = Template::getTags();
6161

62-
while (count($tokens)) {
63-
$token = array_shift($tokens);
62+
for ($i = 0, $n = count($tokens); $i < $n; $i++) {
63+
if ($tokens[$i] === null) {
64+
continue;
65+
}
66+
$token = $tokens[$i];
67+
$tokens[$i] = null;
6468

6569
if ($startRegexp->match($token)) {
6670
$this->whitespaceHandler($token);
@@ -118,7 +122,7 @@ protected function whitespaceHandler($token)
118122
* This assumes that TAG_START is always '{%', and a whitespace control indicator
119123
* is exactly one character long, on a third position.
120124
*/
121-
if (mb_substr($token, 2, 1) === Liquid::get('WHITESPACE_CONTROL')) {
125+
if ($token[2] === Liquid::$config['WHITESPACE_CONTROL']) {
122126
$previousToken = end($this->nodelist);
123127
if (is_string($previousToken)) { // this can also be a tag or a variable
124128
$this->nodelist[key($this->nodelist)] = rtrim($previousToken);
@@ -129,7 +133,7 @@ protected function whitespaceHandler($token)
129133
* This assumes that TAG_END is always '%}', and a whitespace control indicator
130134
* is exactly one character long, on a third position from the end.
131135
*/
132-
self::$trimWhitespace = mb_substr($token, -3, 1) === Liquid::get('WHITESPACE_CONTROL');
136+
self::$trimWhitespace = $token[-3] === Liquid::$config['WHITESPACE_CONTROL'];
133137
}
134138

135139
/**
@@ -254,7 +258,7 @@ private function blockName()
254258
*/
255259
private function createVariable($token)
256260
{
257-
$variableRegexp = new Regexp('/^' . Liquid::get('VARIABLE_START') . Liquid::get('WHITESPACE_CONTROL') . '?(.*?)' . Liquid::get('WHITESPACE_CONTROL') . '?' . Liquid::get('VARIABLE_END') . '$/s');
261+
$variableRegexp = new Regexp('/^' . Liquid::$config['VARIABLE_START'] . Liquid::$config['WHITESPACE_CONTROL'] . '?(.*?)' . Liquid::$config['WHITESPACE_CONTROL'] . '?' . Liquid::$config['VARIABLE_END'] . '$/s');
258262
if ($variableRegexp->match($token)) {
259263
return new Variable($variableRegexp->matches[1]);
260264
}

src/Liquid/Tag/TagRaw.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,12 @@ public function parse(array &$tokens)
3636

3737
$this->nodelist = array();
3838

39-
while (count($tokens)) {
40-
$token = array_shift($tokens);
39+
for ($i = 0, $n = count($tokens); $i < $n; $i++) {
40+
if ($tokens[$i] === null) {
41+
continue;
42+
}
43+
$token = $tokens[$i];
44+
$tokens[$i] = null;
4145

4246
if ($tagRegexp->match($token)) {
4347
// If we found the proper block delimiter just end parsing here and let the outer block proceed

0 commit comments

Comments
 (0)