perf: avoid cloning in parser advanceBy

This commit is contained in:
Evan You 2019-09-19 13:59:24 -04:00
parent 4c3e7e331a
commit 81fd694dd7
3 changed files with 16 additions and 7540 deletions

View File

@ -1,4 +1,5 @@
import { ErrorCodes, CompilerError, createCompilerError } from './errors'
import { assert, advancePositionWithMutation } from './utils'
import {
Namespace,
Namespaces,
@ -15,7 +16,6 @@ import {
TextNode,
ChildNode
} from './ast'
import { assert, advancePositionBy } from './utils'
export interface ParserOptions {
isVoidTag?: (tag: string) => boolean // e.g. img, br, hr
@ -794,15 +794,9 @@ function startsWith(source: string, searchString: string): boolean {
}
function advanceBy(context: ParserContext, numberOfCharacters: number): void {
__DEV__ && assert(numberOfCharacters <= context.source.length)
const { source } = context
const pos = advancePositionBy(context, source, numberOfCharacters)
advancePositionWithMutation(context, source, numberOfCharacters)
context.source = source.slice(numberOfCharacters)
context.offset = pos.offset
context.line = pos.line
context.column = pos.column
}
function advanceSpaces(context: ParserContext): void {

View File

@ -24,23 +24,29 @@ export function advancePositionBy(
source: string,
numberOfCharacters: number
): Position {
__DEV__ && assert(numberOfCharacters <= source.length)
return advancePositionWithMutation({ ...pos }, source, numberOfCharacters)
}
const newPosition = {
...pos
}
// advance by mutation without cloning (for performance reasons), since this
// gets called a lot in the parser
export function advancePositionWithMutation(
pos: Position,
source: string,
numberOfCharacters: number
): Position {
__DEV__ && assert(numberOfCharacters <= source.length)
const str = source.slice(0, numberOfCharacters)
const lines = str.split(/\r?\n/)
newPosition.offset += numberOfCharacters
newPosition.line += lines.length - 1
newPosition.column =
pos.offset += numberOfCharacters
pos.line += lines.length - 1
pos.column =
lines.length === 1
? pos.column + numberOfCharacters
: Math.max(1, lines.pop()!.length)
return newPosition
return pos
}
export function assert(condition: boolean, msg?: string) {