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

View File

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