@jarvinenemil are you using m/validator
or m/validate
? the latter is a convenience fn for one-shot things: if given schema syntax, for every call, it parses it, creates the Schema instance tree and creates a pure validator for it and runs it once and throws it away. m/validator
returns that pure validation function of x -> boolean
, so if you can keep that, you pay for the parsing & optimizing just once.
same applies to m/explain
vs m/explainer
, m/decode
vs m/decoder
etc.
https://github.com/metosin/malli/blob/master/src/malli/core.cljc#L1079-L1085
at best, given a deeply nested schema with 1k fields, the m/decoder
can return a indentity
function if there are no decoding functions mapped to any of the fields or structure in general. Can't get much faster than that ๐
@ikitommi I did a one off using validate. validator was just what I was looking for, thanks!
curious about the perceived perf gains, hopefully many orders of magnitude..
WIP, https://github.com/metosin/malli/pull/283:
(def registry (merge (m/default-schemas) (mu/schemas)))
(def Merged
(m/schema
[:merge
[:map [:x :string]]
[:map [:y :int]]]
{:registry registry}))
Merged
;[:merge
; [:map [:x :string]]
; [:map [:y :int]]]
(m/deref Merged)
;[:map
; [:x :string]
; [:y :int]]
(m/validate Merged {:x "kikka", :y 6})
; => true
just :merge
, :union
and :select-keys
now, should be easy to add more, with the util helpers. current Schema impls in malli.util
:
(defn -merge [] (-util-schema {:type :merge, :f (-reducing merge)}))
(defn -union [] (-util-schema {:type :union, :f (-reducing union)}))
(defn -select-keys [] (-util-schema {:type :select-keys, :min 2, :max 2, :f (-applying select-keys)}))
Using validate
(cc/quick-bench (m/validate schema {}))
Evaluation count : 6 in 6 samples of 1 calls.
Execution time mean : 21.971360 sec
Execution time std-deviation : 2.848014 sec
Execution time lower quantile : 20.065855 sec ( 2.5%)
Execution time upper quantile : 26.840086 sec (97.5%)
Overhead used : 7.984810 ns
Using validator
(cc/quick-bench (validator {}))
Evaluation count : 31504632 in 6 samples of 5250772 calls.
Execution time mean : 12.055681 ns
Execution time std-deviation : 0.575152 ns
Execution time lower quantile : 11.599548 ns ( 2.5%)
Execution time upper quantile : 12.803005 ns (97.5%)
Overhead used : 7.984810 ns
that's 9 orders of magnitude ๐ฎ๐ฎ๐ฎ . Are you starting a power plan while creating the schema as it takes 20 seconds???
anyway, good reason to cache the validator :)
I converted a excel-sheet from business people to a malli schema so I can convert the malli schema to a json-schema that can be used from several languages ๐
I anonymized the fields and havent added regexp yet but just to give u an idea on how big this thing is. @ikitommi I did not decide this, the real world is sometimes a bit messy ๐.
๐ Iโm looking for a way to use an accumulator during a schema walk.
There might be a way to bridge Specter and Malli for that purpose.
Thatโs easy to hack from the outside in with say an atom but I was wondering if there is cleaner way to do this from the inside out instead?
It seems like itโd be possible to reify a Walker that expects the walk fn to return [schema context]
and merges the returned context into the options to pass to the next stepโฆ
yes, you should implement a custom Walker
. find-first
might be a good example for that: https://github.com/metosin/malli/blob/master/src/malli/util.cljc#L37-L51
or: subschemas
: https://github.com/metosin/malli/blob/master/src/malli/util.cljc#L150-L163
Thanks for the pointers!
I guess doing this without some atom would require some kind of state monad so I think Iโll stick with your examples ๐
if you get a generic accumulating walker, might be a good example in https://github.com/metosin/malli/blob/master/docs/tips.md.
@ikitommi can I have docstring for spec in swagger output?
@mike1452 what kind of docstring are you looking for? :title
, :description
and :default
are automatically copied to both JSON Schema and Swagger.
JSON Schema references