New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance fixes #14

Merged
merged 10 commits into from Jan 14, 2018

replace array slicing for improved speed

  • Loading branch information...
mike42 committed Jan 13, 2018
commit ee7aa1852a0cea8fa0d1b473f64fcc3069dd9277
@@ -309,12 +309,6 @@ private static function tagIsAt(array $tag, array $textChars, int $position)
}
return $match;
}
private static function tagIsAtString(string $tag, array $textChars, int $position)
{
$tagChars = self::explodeString($tag);
return self::tagIsAt($tagChars, $textChars, $position);
}
/**
* Parse a block of wikitext looking for inline tokens, indicating the start of an element.
@@ -323,7 +317,7 @@ private static function tagIsAtString(string $tag, array $textChars, int $positi
* @param string $text Text to parse
* @param $token The name of the current inline element, if inside one.
*/
private function parseInline(array $textChars, string $token = '')
private function parseInline(array $textChars, string $token = '', $idxFrom = 0)
{
/* Quick escape if we've run into a table */
$inParagraph = false;
@@ -346,7 +340,7 @@ private function parseInline(array $textChars, string $token = '')
$curKey = '';
$len = count($textChars);
for ($i = 0; $i < $len; $i++) {
for ($i = $idxFrom; $i < $len; $i++) {
/* Looping through each character */
$hit = false; // State so that the last part knows whether to simply append this as an unmatched character
$c = $textChars[$i];
@@ -362,7 +356,6 @@ private function parseInline(array $textChars, string $token = '')
if (self::tagIsAt($inlineElement -> endTag, $textChars, $i)) {
/* Hit a close tag: Stop parsing here, return the remainder, and let the parent continue */
$start = $i + count($inlineElement -> endTag);
$remainderChars = array_slice($textChars, $start, $len - $start);
if ($inlineElement -> hasArgs) {
/* Handle arguments if needed */
@@ -376,7 +369,7 @@ private function parseInline(array $textChars, string $token = '')
/* Clean up and quit */
$parsed .= $buffer; /* As far as I can tall $inPargraph should always be false here? */
return array('parsed' => $parsed, 'remainderChars' => $remainderChars);
return array('parsed' => $parsed, 'remainderIdx' => $start);
}
/* Next priority is looking for this element's agument tokens if applicable */
@@ -411,27 +404,23 @@ private function parseInline(array $textChars, string $token = '')
if (!$hit && self::tagIsAt($child -> startTag, $textChars, $i)) {
/* Hit a symbol. Parse it and keep going after the result */
$start = $i + count($child -> startTag);
$remainderChars = array_slice($textChars, $start, $len - $start);
/* Regular, recursively-parsed element */
$result = $this -> parseInline($remainderChars, $key);
$result = $this -> parseInline($textChars, $key, $start);
$buffer .= self::$backend -> encapsulateElement($key, $result['parsed']);
$textChars = $result['remainderChars'];
$len = count($textChars);
$i = -1;
$i = $result['remainderIdx'] - 1;
$hit = true;
}
}
}
if (!$hit) {
if ($c == "\n") {
if ($c == "\n" && $i < $len - 1) {
if (self::tagIsAt(self::$tableStart -> startTag, $textChars, $i + 1)) {
$hit = true;
$start = $i + 1 + count(self::$tableStart -> startTag);
$key = 'table';
} else if ($i < $len - 1) {
} else {
/* Check for non-table line-based stuff coming up next, each time \n is found */
$next = $textChars[$i + 1];
foreach (self::$lineBlock as $key => $block) {
@@ -447,12 +436,11 @@ private function parseInline(array $textChars, string $token = '')
if ($hit) {
/* Go over what's been found */
$remainderChars = array_slice($textChars, $start, $len - $start);
if ($key == 'table') {
$result = $this -> parseTable($remainderChars);
$result = $this -> parseTable($textChars, $start);
} else {
/* Let parseLineBlock take care of this on a per-line basis */
$result = $this -> parseLineBlock($remainderChars, $key);
$result = $this -> parseLineBlock($textChars, $key, $start);
}
if ($buffer != '') {
/* Something before this was part of a paragraph */
@@ -462,9 +450,7 @@ private function parseInline(array $textChars, string $token = '')
$buffer = "";
/* Now append this non-paragraph element */
$parsed .= $result['parsed'];
$textChars = $result['remainderChars'];
$len = count($textChars);
$i = -1;
$i = $result['remainderIdx'] - 1;
}
/* Other \n-related things if it wasn't as exciting as above */
@@ -481,7 +467,7 @@ private function parseInline(array $textChars, string $token = '')
if ($token == 'td') {
/* We only get here from table syntax if something else was being parsed, so we can quit here */
$parsed = $buffer;
return array('parsed' => $parsed, 'remainderChars' => $textChars);
return array('parsed' => $parsed, 'remainderIdx' => $i);
}
}
@@ -502,7 +488,7 @@ private function parseInline(array $textChars, string $token = '')
$parsed .= $buffer;
}
return array('parsed' => $parsed, 'remainderChars' => []);
return array('parsed' => $parsed, 'remainderIdx' => $i);
}
/**
@@ -511,13 +497,13 @@ private function parseInline(array $textChars, string $token = '')
* @param $text Wikitext block to parse
* @param $token name of the LineBlock token which we suspect
*/
private function parseLineBlock(array $textChars, string $token)
private function parseLineBlock(array $textChars, string $token, $fromIdx = 0)
{
/* Block element we are using */
$lineBlockElement = self::$lineBlock[$token];
// Attempted re-write
$lineStart = 0;
$lineStart = $fromIdx;
$list = [];
while (($lineLen = self::getLineLen($textChars, $lineStart)) !== false) {
$startTokenLen = self::countChar($lineBlockElement -> startChar, $textChars, $lineStart, $lineBlockElement -> limit);
@@ -547,8 +533,7 @@ private function parseLineBlock(array $textChars, string $token)
$list = self::makeList($list);
}
$parsed = self::$backend -> renderLineBlock($token, $list);
$remainderChars = array_slice($textChars, $lineStart);
return array('parsed' => $parsed, 'remainderChars' => $remainderChars);
return array('parsed' => $parsed, 'remainderIdx' => $lineStart);
}
/**
@@ -557,10 +542,10 @@ private function parseLineBlock(array $textChars, string $token)
* @param string $text Text to parse
* @return multitype:string parsed and remaining text
*/
private function parseTable(array $textChars)
private function parseTable(array $textChars, $fromIdx = 0)
{
$lineLen = self::getLineLen($textChars, 0);
$propertiesChars = array_slice($textChars, 0, $lineLen);
$lineLen = self::getLineLen($textChars, $fromIdx);
$propertiesChars = array_slice($textChars, $fromIdx, $lineLen);
$table['properties'] = implode($propertiesChars);
$table['row'] = [];
$lineStart = $lineLen + 1;
@@ -590,8 +575,7 @@ private function parseTable(array $textChars)
}
/* Clobber the remaining text together and throw it to the cell parser */
$result = $this -> parseTableCells($token, $textChars, $contentStart, $tmpRow['col']);
$textChars = $result['remainderChars'];
$lineStart = 0;
$lineStart = $result['remainderIdx'];
$lineLen = -1;
$tmpRow['col'] = $result['col'];
} elseif ($token == 'tr') {
@@ -615,8 +599,7 @@ private function parseTable(array $textChars)
$table['row'][] = $tmpRow;
}
$parsed = self::$backend -> renderTable($table);
$remainderChars = array_slice($textChars, $lineStart);
return array('parsed' => $parsed, 'remainderChars' => $remainderChars);
return array('parsed' => $parsed, 'remainderIdx' => $lineStart);
}
private static function getLineLen(array $textChars, int $position)
@@ -681,12 +664,10 @@ private function parseTableCells(string $token, array $textChars, int $from, arr
if ($hit) {
/* Parse whatever it is and return here */
$start = $i;
$remainderChars = array_slice($textChars, $start, $len - $start);
$result = $this -> parseInline($remainderChars, 'td');
$result = $this -> parseInline($textChars, 'td', $start);
$buffer .= $result['parsed'];
$textChars = $result['remainderChars'];
$len = count($textChars);
$i = -1;
// TODO was -1 before
$i = $result['remainderIdx'];
}
if (!$hit && self::tagIsAt($tableElement -> inlinesep, $textChars, $i)) {
@@ -730,8 +711,7 @@ private function parseTableCells(string $token, array $textChars, int $from, arr
$tmpCol['content'] = $buffer;
$colsSoFar[] = $tmpCol;
$start = $i + 1;
$remainderChars = array_slice($textChars, $start, $len - $start);
return array('col' => $colsSoFar, 'remainderChars' => $remainderChars);
return array('col' => $colsSoFar, 'remainderIdx' => $start);
}
private static function countChar(array $chars, array $text, int $position, int $max = 0)
{
ProTip! Use n and p to navigate between commits in a pull request.