Skip to content

Commit

Permalink
Merge pull request #526 from metosin/fast-entry-parsing
Browse files Browse the repository at this point in the history
faster entry parsing, part1
  • Loading branch information
ikitommi authored Aug 24, 2021
2 parents b154b39 + c7fc874 commit 27eef27
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 19 deletions.
3 changes: 2 additions & 1 deletion perf/malli/creation_perf_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
(bench (m/schema :int))
(profile (m/schema :int))

;; 44µs -> 31µs
;; 44µs -> 31µs -> 18µs
(bench (m/schema ?schema))
(profile (m/schema ?schema)))

Expand All @@ -116,6 +116,7 @@
;; 51µs
;; 44µs (-set-children, -set-properties)
;; 29µs (lot's of stuff)
;; 21µs (faster parsing)
(bench (mu/closed-schema schema))
(profile (mu/closed-schema schema)))

Expand Down
39 changes: 21 additions & 18 deletions src/malli/core.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -215,22 +215,26 @@
:always (->> (filter (fn [e] (-> e last some?)))))]
(-set-children schema children)))

(defn -parse-entries [children {:keys [naked-keys lazy-refs]} options]
(let [-parse (fn [e] (let [[[k ?p ?v] f] (cond
(not (sequential? e)) (if (and naked-keys (-reference? e)) [[e nil e] e] (-fail! ::invalid-ref {:ref e}))
(and (= 1 (count e)) (-reference? (first e))) (if naked-keys [[(first e) nil (first e)] e])
(and (= 2 (count e)) (-reference? (first e)) (map? (last e))) (if naked-keys [(conj e (first e)) e])
:else [e (->> (-update (vec e) (dec (count e)) (-comp -form #(schema % options))) (keep identity) (vec))])
[p ?s] (if (or (nil? ?p) (map? ?p)) [?p ?v] [nil ?p])
s (cond-> (or ?s (if (-reference? k) f)) lazy-refs (-lazy options))
c [k p (schema s options)]]
{:children [c]
:entries [(miu/-tagged k (-val-schema (last c) p))]
:forms [f]}))
es (reduce #(merge-with into %1 %2) {} (mapv -parse children))
keys (->> es :entries (map first))]
(when-not (= keys (distinct keys))
(-fail! ::non-distinct-entry-keys {:keys keys}))
(defn -parse-entries [cs {:keys [naked-keys lazy-refs]} options]
(let [-parse (fn [e]
(let [[[k ?p ?v] f]
(if (not (sequential? e))
(if (and naked-keys (-reference? e))
[[e nil e] e]
(-fail! ::invalid-ref {:ref e}))
(let [size (count e), k (nth e 0)]
(or (if (-reference? k)
(cond (= 1 size) (if naked-keys [[k nil k] e])
(and (= 2 size) (map? (nth e 1))) (if naked-keys [(conj e k) e])))
[e (->> (-update (vec e) (dec (count e)) (-comp -form #(schema % options))) (keep identity) (vec))])))
[p ?s] (if (or (nil? ?p) (map? ?p)) [?p ?v] [nil ?p])
s (cond-> (or ?s (if (-reference? k) f)) lazy-refs (-lazy options))
c [k p (schema s options)]]
[k c (miu/-tagged k (-val-schema (nth c 2) p)) f]))
es (loop [keyset #{}, children [], entries [], forms [], [p & ps] (map -parse cs)]
(if p (recur (conj keyset (nth p 0)) (conj children (nth p 1)) (conj entries (nth p 2)) (conj forms (nth p 3)) ps)
{:keyset keyset, :children children, :entries entries, :forms forms}))]
(when-not (= (count (:keyset es)) (count cs)) (-fail! ::non-distinct-entry-keys es))
es))

(defn -guard [pred tf]
Expand Down Expand Up @@ -686,9 +690,8 @@
(-properties-schema [_ _])
(-children-schema [_ _])
(-into-schema [parent {:keys [closed] :as properties} children options]
(let [{:keys [children entries forms]} (-parse-entries children opts options)
(let [{:keys [keyset children entries forms]} (-parse-entries children opts options)
form (-create-form :map properties forms)
keyset (->> entries (map first) (set))
->parser (fn [f] (let [parsers (cond-> (mapv
(fn [[key {:keys [optional]} schema]]
(let [parser (f schema)]
Expand Down

0 comments on commit 27eef27

Please sign in to comment.