`s/fn` validation has extra overhead
frenchy64 opened this issue · 3 comments
The (@~input-checker-sym args#)
in the input checker code could be faster in the most common case without a rest argument and be more like (@~input-checker-sym ~@bind-syms)
.
(when-let [error# (@~input-checker-sym args#)]
(error! (utils/format* "Input to %s does not match schema: \n\n\t \033[0;33m %s \033[0m \n\n"
'~fn-name (pr-str error#))
{:schema ~input-schema-sym :value args# :error error#})))))
Perhaps a new macro called something like schema.core/arguments-checker
could expand like this:
(arguments-checker 'my-fn-name ([a :- s/Int] [b :- s/Int, c :- s/Num] ))
;=>
(let [a_chk (checker s/Int)
b_chk (checker s/Int)
c_chk (checker s/Num)
input_schema1 [(s/one a_chk 'a)]
input_schema2 [(s/one a_chk 'b)
(s/one a_chk 'c)]]
(fn
([a]
(let [a_err (a_chk a)]
(when a_err
(let [error [(list 'named a_err a)]]
(error! (utils/format* "Input to %s does not match schema: \n\n\t \033[0;33m %s \033[0m \n\n"
'my-fn-name (pr-str error))
{:schema input-schema1 :value [a] :error error})))))
([b c]
(let [b_err (b_chk b)
c_err (c_chk c)]
(when (or b_err c_err)
(let [error (mapv (fn [[n err]]
(when err
(list 'named err n)))
[[b b_err] [c c_err]])]
(error! (utils/format* "Input to %s does not match schema: \n\n\t \033[0;33m %s \033[0m \n\n"
'my-fn-name (pr-str error))
{:schema input-schema2 :value [b c] :error error})))))))
Interesting! A few questions:
- How significant is the overhead of the list compared to the typical overhead of checking itself?
- Would this require a lot of code duplication, or do you think we can just refactor the existing checks?
- How will this tile with
fn-validator
?
How significant is the overhead of the list compared to the typical overhead of checking itself?
Haven't done any perf tests, just a hunch for now. I happened to be reading the schema.macros
implementation with my performance hat on. I'll try some tests with the prototype.
Would this require a lot of code duplication, or do you think we can just refactor the existing checks?
I think it could replace the existing checks if it works out in practice. It may be a challenge to manage method size, I tried to factor out as much code as I could into defn
's in my prototype.
How will this tile with
fn-validator
?
Nothing needs to change there I think.