shouldBeExcluded() scanned every excluded attribute with Str::startsWith,
and excludeAttribute() ran array_unique on the whole list after each
insert. validated() ran preg_grep over every rule key for each array or
list rule. With wildcard rules and exclude_* rules, all three grow with
the number of rows, so validation time grew quadratically.
Key the excluded attributes by name and check each dotted prefix of an
attribute against them. Compute the set of rule keys that have nested
rules once per validated() call.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>