diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index b4f8565fb..86894494f 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,9 @@ # Release Notes +## 8.2.1 - Sep 28 2026 + +- Perf: `JsonSchema.validate` now caches compiled `Regex` instances per `pattern`, instead of recompiling a new `Regex` for every string value validated against a schema `pattern` constraint. No behavior change. + ## 8.2.0 - Jul 06 2026 - Fix: HTML hexadecimal character references (`A`) are now decoded correctly; previously digit-only hex refs were parsed as decimal and refs containing `a`–`f` were left as literal text. diff --git a/src/FSharp.Data.Json.Core/JsonSchema.fs b/src/FSharp.Data.Json.Core/JsonSchema.fs index a25083e50..6f677928e 100644 --- a/src/FSharp.Data.Json.Core/JsonSchema.fs +++ b/src/FSharp.Data.Json.Core/JsonSchema.fs @@ -366,6 +366,14 @@ module JsonSchema = resolve schema + // Cache compiled regexes by pattern so repeated validation of many values against + // the same schema pattern (e.g. array/object properties) doesn't recompile the regex each time. + let private patternRegexCache = + System.Collections.Concurrent.ConcurrentDictionary() + + let private getPatternRegex (pattern: string) = + patternRegexCache.GetOrAdd(pattern, (fun p -> System.Text.RegularExpressions.Regex(p))) + /// Validate a JSON value against a schema let rec validate (schema: JsonSchemaDefinition) (value: JsonValue) : ValidationResult = // Check nulls first @@ -388,7 +396,7 @@ module JsonSchema = // Validate pattern match schema.Pattern with | Some pattern -> - let regex = System.Text.RegularExpressions.Regex(pattern) + let regex = getPatternRegex pattern if regex.IsMatch(str) then Valid