Skip to content

Build filter regexes interpreted instead of compiled [patch] - #174

Open
matt-edmondson wants to merge 1 commit into
mainfrom
fix/144-interpreted-regex
Open

matt-edmondson wants to merge 1 commit into
mainfrom
fix/144-interpreted-regex

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #144

What changed

  • DoesMatchRegex no longer passes RegexOptions.Compiled. A filter box makes a new pattern on every keystroke and matches it once, so compiling each one to IL cost more than it saved. IgnoreCase and CultureInvariant are unchanged, and so is the comment explaining them.
  • The invalid-pattern fallback RegexMatchAnything used to be a method that built and compiled a new .* on every call. It is now a single static readonly instance, interpreted and bounded by RegexMatchTimeout, in the same way as RegexMatchNothing.
  • Regex construction is moved into an internal CreateFilterRegex, so tests can check the options directly. They don't have to read the shared cache, which parallel tests keep clearing.

Matching behaviour is the same: the only differences are the options and the identity of the fallback instance.

Tests

  • FilterRegexesAreInterpretedNotCompiled runs under both sensitivities. It checks that Compiled is absent, that CultureInvariant is still set, that IgnoreCase follows the sensitivity, and that the 1 s timeout still applies.
  • AnInvalidRegexFilterSharesOneInterpretedMatchAnythingInstance checks that [ and (unclosed return the same instance. That instance is not compiled, keeps the timeout, and still matches anything through DoesMatchRegex.
  • With the options and the fallback reverted to the compiled versions, 3 tests fail. With the fix, the full suite passes on net10.0: 216/216.

I didn't add a benchmark. The issue lists one as optional.


Generated by Claude Code

A filter box makes a new pattern on every keystroke and matches it once,
so RegexOptions.Compiled cost far more than it saved: about ten times the
per-keystroke work and several times the memory of a full cache. The
invalid-pattern fallback is now one shared, interpreted instance with the
match timeout, instead of a newly compiled ".*" on every call.

Fixes #144

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017vfJW2nwQnKNnZqSnbuUxe
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Every new regex filter is compiled to IL (RegexOptions.Compiled): ~0.75 ms per keystroke and ~4x the cache memory for patterns that are used once

1 participant