Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
10 changes: 9 additions & 1 deletion src/FSharp.Data.Json.Core/JsonSchema.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, System.Text.RegularExpressions.Regex>()

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
Expand All @@ -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
Expand Down
Loading