Speedup Parsers.validID

It turned up in profiling sessions. Previously, it used parser combinators
which are somewhat slow especially when the JVM is still cold.

The grammar for ID is simple enough to afford this handwritten parser.
This commit is contained in:
Johannes Rudolph 2018-02-07 16:10:48 +01:00
parent bde197f2fc
commit 9370a2adf0
No known key found for this signature in database
GPG Key ID: 4D293A24CCD39E19
1 changed files with 18 additions and 6 deletions

View File

@ -12,15 +12,17 @@ import Parser._
import java.io.File
import java.net.URI
import java.lang.Character.{
getType,
MATH_SYMBOL,
OTHER_SYMBOL,
CURRENCY_SYMBOL,
DASH_PUNCTUATION,
OTHER_PUNCTUATION,
MATH_SYMBOL,
MODIFIER_SYMBOL,
CURRENCY_SYMBOL
OTHER_PUNCTUATION,
OTHER_SYMBOL,
getType
}
import scala.annotation.tailrec
/** Provides standard implementations of commonly useful [[Parser]]s. */
trait Parsers {
@ -313,6 +315,16 @@ object DefaultParsers extends Parsers with ParserMain {
apply(p)(s).resultEmpty.isValid
/** Returns `true` if `s` parses successfully according to [[ID]].*/
def validID(s: String): Boolean = matches(ID, s)
def validID(s: String): Boolean = {
// Handwritten version of `matches(ID, s)` because validID turned up in profiling.
def isIdChar(c: Char): Boolean = Character.isLetterOrDigit(c) || (c == '_')
@tailrec def isRestIdChar(cur: Int, s: String, length: Int): Boolean =
if (cur < length)
isIdChar(s.charAt(cur)) && isRestIdChar(cur + 1, s, length)
else
true
!s.isEmpty && Character.isLetter(s.charAt(0)) && isRestIdChar(1, s, s.length)
}
}