Commit 005a6a19 authored by Scott Wolchok's avatar Scott Wolchok Committed by Jesse Beder
Browse files

Avoid copying cached RegExes for scalars

This improves performance on the test.yaml attached to #158 by about
25% on my machine as compared to the previous commit (0.25s -> 0.20s),
as measured by `time build/util/parse < test.yaml > /dev/null`.
parent 8c35a8ff
...@@ -20,6 +20,10 @@ namespace YAML { ...@@ -20,6 +20,10 @@ namespace YAML {
namespace Exp { namespace Exp {
// misc // misc
inline const RegEx& Empty() {
static const RegEx e;
return e;
}
inline const RegEx& Space() { inline const RegEx& Space() {
static const RegEx e = RegEx(' '); static const RegEx e = RegEx(' ');
return e; return e;
......
...@@ -28,13 +28,17 @@ std::string ScanScalar(Stream& INPUT, ScanScalarParams& params) { ...@@ -28,13 +28,17 @@ std::string ScanScalar(Stream& INPUT, ScanScalarParams& params) {
std::string scalar; std::string scalar;
params.leadingSpaces = false; params.leadingSpaces = false;
if (!params.end) {
params.end = &Exp::Empty();
}
while (INPUT) { while (INPUT) {
// ******************************** // ********************************
// Phase #1: scan until line ending // Phase #1: scan until line ending
std::size_t lastNonWhitespaceChar = scalar.size(); std::size_t lastNonWhitespaceChar = scalar.size();
bool escapedNewline = false; bool escapedNewline = false;
while (!params.end.Matches(INPUT) && !Exp::Break().Matches(INPUT)) { while (!params.end->Matches(INPUT) && !Exp::Break().Matches(INPUT)) {
if (!INPUT) if (!INPUT)
break; break;
...@@ -87,7 +91,7 @@ std::string ScanScalar(Stream& INPUT, ScanScalarParams& params) { ...@@ -87,7 +91,7 @@ std::string ScanScalar(Stream& INPUT, ScanScalarParams& params) {
break; break;
// are we done via character match? // are we done via character match?
int n = params.end.Match(INPUT); int n = params.end->Match(INPUT);
if (n >= 0) { if (n >= 0) {
if (params.eatEnd) if (params.eatEnd)
INPUT.eat(n); INPUT.eat(n);
......
...@@ -19,7 +19,8 @@ enum FOLD { DONT_FOLD, FOLD_BLOCK, FOLD_FLOW }; ...@@ -19,7 +19,8 @@ enum FOLD { DONT_FOLD, FOLD_BLOCK, FOLD_FLOW };
struct ScanScalarParams { struct ScanScalarParams {
ScanScalarParams() ScanScalarParams()
: eatEnd(false), : end(nullptr),
eatEnd(false),
indent(0), indent(0),
detectIndent(false), detectIndent(false),
eatLeadingWhitespace(0), eatLeadingWhitespace(0),
...@@ -32,7 +33,8 @@ struct ScanScalarParams { ...@@ -32,7 +33,8 @@ struct ScanScalarParams {
leadingSpaces(false) {} leadingSpaces(false) {}
// input: // input:
RegEx end; // what condition ends this scalar? const RegEx* end; // what condition ends this scalar?
// unowned.
bool eatEnd; // should we eat that condition when we see it? bool eatEnd; // should we eat that condition when we see it?
int indent; // what level of indentation should be eaten and ignored? int indent; // what level of indentation should be eaten and ignored?
bool detectIndent; // should we try to autodetect the indent? bool detectIndent; // should we try to autodetect the indent?
......
...@@ -298,7 +298,7 @@ void Scanner::ScanPlainScalar() { ...@@ -298,7 +298,7 @@ void Scanner::ScanPlainScalar() {
// set up the scanning parameters // set up the scanning parameters
ScanScalarParams params; ScanScalarParams params;
params.end = params.end =
(InFlowContext() ? Exp::ScanScalarEndInFlow() : Exp::ScanScalarEnd()); (InFlowContext() ? &Exp::ScanScalarEndInFlow() : &Exp::ScanScalarEnd());
params.eatEnd = false; params.eatEnd = false;
params.indent = (InFlowContext() ? 0 : GetTopIndent() + 1); params.indent = (InFlowContext() ? 0 : GetTopIndent() + 1);
params.fold = FOLD_FLOW; params.fold = FOLD_FLOW;
...@@ -338,7 +338,8 @@ void Scanner::ScanQuotedScalar() { ...@@ -338,7 +338,8 @@ void Scanner::ScanQuotedScalar() {
// setup the scanning parameters // setup the scanning parameters
ScanScalarParams params; ScanScalarParams params;
params.end = (single ? RegEx(quote) && !Exp::EscSingleQuote() : RegEx(quote)); RegEx end = (single ? RegEx(quote) && !Exp::EscSingleQuote() : RegEx(quote));
params.end = &end;
params.eatEnd = true; params.eatEnd = true;
params.escape = (single ? '\'' : '\\'); params.escape = (single ? '\'' : '\\');
params.indent = 0; params.indent = 0;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment