huge speedup to if-path when condition is a single statically known function, big optimization for all transforms that don't use value collection by using identical? instead of empty?

This commit is contained in:
Nathan Marz 2016-06-04 20:49:57 -04:00
parent 94d5d2021a
commit 2d3902f478
3 changed files with 40 additions and 24 deletions

View file

@ -1,7 +1,9 @@
(def VERSION (.trim (slurp "VERSION")))
(defproject com.rpl/specter VERSION
:jvm-opts ["-XX:-OmitStackTraceInFastThrow"] ; this prevents JVM from doing optimizations which can remove stack traces from NPE and other exceptions
:jvm-opts ["-XX:-OmitStackTraceInFastThrow" ; this prevents JVM from doing optimizations which can remove stack traces from NPE and other exceptions
;"-agentpath:/Applications/YourKit_Java_Profiler_2015_build_15056.app/Contents/Resources/bin/mac/libyjpagent.jnilib"
]
:source-paths ["src/clj"]
:java-source-paths ["src/java"]
:test-paths ["test", "target/test-classes"]

View file

@ -506,20 +506,23 @@
(defpathedfn if-path
"Like cond-path, but with if semantics."
([cond-p then-path]
(fixed-pathed-nav [late-cond cond-p
late-then then-path]
(select* [this structure next-fn]
(i/if-select structure next-fn late-cond late-then STOP))
(transform* [this structure next-fn]
(i/if-transform structure next-fn late-cond late-then STOP))))
(if-path cond-p then-path STOP))
([cond-p then-path else-path]
(if-let [afn (i/extract-basic-filter-fn cond-p)]
(fixed-pathed-nav [late-then then-path
late-else else-path]
(select* [this structure next-fn]
(i/if-select structure next-fn afn late-then late-else))
(transform* [this structure next-fn]
(i/if-transform structure next-fn afn late-then late-else)))
(fixed-pathed-nav [late-cond cond-p
late-then then-path
late-else else-path]
(select* [this structure next-fn]
(i/if-select structure next-fn late-cond late-then late-else))
(i/if-select structure next-fn #(i/selected?* late-cond %) late-then late-else))
(transform* [this structure next-fn]
(i/if-transform structure next-fn late-cond late-then late-else)))))
(i/if-transform structure next-fn #(i/selected?* late-cond %) late-then late-else))
))))
(defpathedfn cond-path
"Takes in alternating cond-path path cond-path path...

View file

@ -93,11 +93,11 @@
(fn [params params-idx selector structure]
(selector params params-idx [] structure
(fn [_ _ vals structure]
(if-not (empty? vals) [(conj vals structure)] [structure]))))
(if-not (identical? [] vals) [(conj vals structure)] [structure]))))
(fn [params params-idx transformer transform-fn structure]
(transformer params params-idx [] structure
(fn [_ _ vals structure]
(if (empty? vals)
(if (identical? [] vals)
(transform-fn structure)
(apply transform-fn (conj vals structure))))))
))
@ -757,17 +757,28 @@
(next-fn structure)
))
(defn if-select [structure next-fn late-cond late-then late-else]
(let [apath (if (empty? (compiled-select* late-cond structure))
late-else
late-then)]
(defn extract-basic-filter-fn [path]
(cond (fn? path)
path
(and (coll? path)
(= 1 (count path))
(fn? (first path)))
(first path)
))
(defn if-select [structure next-fn then-tester late-then late-else]
(let [apath (if (then-tester structure)
late-then
late-else)]
(doall (mapcat next-fn (compiled-select* apath structure)))
))
(defn if-transform [structure next-fn late-cond late-then late-else]
(let [apath (if (empty? (compiled-select* late-cond structure))
late-else
late-then)]
(defn if-transform [structure next-fn then-tester late-then late-else]
(let [apath (if (then-tester structure)
late-then
late-else)]
(compiled-transform* apath next-fn structure)
))