Chevrotain
Home
Features
Tutorial
Guide
FAQ
Changes
APIs
Playground
Benchmark
Discussions
GitHub
Home
Features
Tutorial
Guide
FAQ
Changes
APIs
Playground
Benchmark
Discussions
GitHub
  • Guide

    • Introduction
    • Runtime Performance
    • Initialization Performance
    • CST
    • Syntax Diagrams
    • Custom Token Patterns
    • Syntactic Content Assist
    • Internals
    • Resolving Grammar Errors
    • Resolving Lexer Errors

Initialization Performance

Chevrotain is (mostly) a runtime tool (No code generation). This means there is a fair bit of logic happening every time a Chevrotain Parser or Lexer are initialized. In some use cases this overhead may need to be reduced as much as possible.

Enabling Initialization Performance Tracing

Measuring a Parser's initialization performance can be done by enabling the IParserConfig.traceInitPerf flag. For example:

class InitTracingParser extends CstParser {
  constructor() {
    super([], {
      // Note `traceInitPerf` may also accept numerical values
      traceInitPerf: true,
    });

    this.performSelfAnalysis();
  }
}

new InitTracingParser(); // Will print tracing info to the console.

A Lexer's initialization performance can similarly be measured by enabling the ILexerConfig.traceInitPerf flag:

// Will print tracing info to the console.
new Lexer([], {
  // Note `traceInitPerf` may also accept numerical values
  traceInitPerf: true,
});

Use a smaller Global maxLookahead

Chevrotain is a K tokens lookahead Parser, this means it peeks ahead (at most) K Tokens to determine the alternative to pick whenever it encounters a "branching" in the grammar.

During initialization Chevrotain pre-computes and caches lookahead functions that would later be used at runtime. The global maxLookahead setting can significantly affect the performance of this pre-computation due to the fact the number of possible "paths" in the grammar can grow exponentially as the max length of the possible paths increases.

Example:

class LowLookaheadParser extends CstParser {
  constructor() {
    super([], {
      // By default this value is 3
      maxLookahead: 2,
    });

    this.performSelfAnalysis();
  }
}

Note that the global maxLookahead can be overridden for individual DSL methods(OR/OPTION/MANY/...) invocations, For example:

class LowLookaheadParser extends CstParser {
  constructor() {
    super([], {
      // Globally **only one** token lookahead.
      maxLookahead: 1,
    });

    $.RULE("value", () => {
      $.OR({
        // We need **two** tokens lookahead to distinguish between these two alternatives
        MAX_LOOKAHEAD: 2,
        DEF: [
          {
            ALT: () => {
              $.CONSUME(A);
              $.CONSUME(B);
            },
          },
          {
            ALT: () => {
              $.CONSUME(A);
              $.CONSUME(C);
            },
          },
        ],
      });
    });

    this.performSelfAnalysis();
  }
}

Disabling Grammar Validations

Chevrotain performs many validations during Lexer & Parser initialization, however those are not really relevant when the Lexer & Parser are known to be valid, These validations are a development time tool, and not really needed during productive flows.

The IParserConfig.skipValidations config property can be used to avoid running these validations during Parser initialization.

class NaiveSkippedValidationsParser extends CstParser {
  constructor() {
    super([], {
      // This could reduce 30-50% of the initialization time
      skipValidations: true,
    });

    this.performSelfAnalysis();
  }
}

Similarly the ILexerConfig.skipValidations config property can be used to skip the optional validations during Lexer initialization.

new Lexer([], {
  skipValidations: true,
});

The examples above are a little naive, as the validations are always skipped, while we only need to skip them under specific conditions, for example:

class MoreRealisticSkippedValidationsParser extends CstParser {
  constructor() {
    super([], {
      // only run the validations when a certain env variable is set.
      skipValidations: process.env["IN_MY_PACKAGE_LOCAL_TESTING"] !== true,
      // Always Trace init logs when in local testing to hopefully spot regressions.
      traceInitPerf: process.env["IN_MY_PACKAGE_LOCAL_TESTING"] === true,
    });

    this.performSelfAnalysis();
  }
}

Note that in a real world scenario the special condition to enable validations/tracing could be anything:

  • env variable.
  • command line argument.
  • existence of a certain config file in the CWD.
  • ...
Edit this page on GitHub
Last Updated: 1/24/26, 5:39 PM
Contributors: bd82, Shahar Soel, I060847, Gaurav
Prev
Runtime Performance
Next
CST