Description
The idea here would be to first validate the less costly options. E.g. in unions
we'd start with the less costly option, in typed-dict we'd go through the fields in order of cost.
We could do this by adding a cost
to BuildValidator
:
trait BuildValidator {
fn cost(&self) -> usize {
// return the max usize by default
}
Then at build time we can "sort" choices by least cost.
Costs can be calculated recursively, e.g. a typed-dict
schema can be the sum of the cost of it's fields while a list
can be the cost of it's item validator * some fixed heuristic number like 1000
to represent a "medium sized list" (this could even be adjusted dynamically at runtime, but that's a matter for muuuuch in the future).
In combination with the idea of #430 this could go a long way towards making a non-tagged union much more performant. You can imagine that if we have a union like:
class Branch1:
x: int
y: List[Expensive]
class Branch2:
x: date
y: List[Expensive]
We would always validate the x
field first and short circuit as soon as that fails. So passing in {"x": "2023-03-10", "y": [...]}
would be very performant.