Skip to content

Commit

Permalink
redplanetlabs#223 - Improve before-index performance
Browse files Browse the repository at this point in the history
Adding before-index implementation that uses take/drop instead of setval/srange

Adding new functional test to confirm behavior when operating on a string

Adding benchmark for old versus new implementation of before-index
  • Loading branch information
jeff303 committed Aug 3, 2020
1 parent 40add56 commit 5e51ef1
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 2 deletions.
6 changes: 6 additions & 0 deletions scripts/benchmarks.clj
Expand Up @@ -335,3 +335,9 @@
(transform (walker number?) inc data)
(transform (walker-old number?) inc data)
))

(let [data (vec (range 1000)) insert-idx 500]
(run-benchmark "old versus new before-index implementation"
(setval (before-index-old insert-idx) -1 data)
(setval (before-index-new insert-idx) -1 data)
))
24 changes: 23 additions & 1 deletion src/clj/com/rpl/specter.cljc
Expand Up @@ -968,7 +968,7 @@
(defrichnav
^{:doc "Navigates to the empty space between the index and the prior index. For select
navigates to NONE, and transforms to non-NONE insert at that position."}
before-index
before-index-old
[index]
(select* [this vals structure next-fn]
NONE)
Expand All @@ -980,6 +980,28 @@
(setval (srange index index) [v] structure)
))))

(defrichnav
^{:doc "Navigates to the empty space between the index and the prior index. For select
navigates to NONE, and transforms to non-NONE insert at that position."}
before-index-new
[index]
(select* [this vals structure next-fn]
NONE)
(transform* [this vals structure next-fn]
(let [v (next-fn vals NONE)]
(if (identical? NONE v)
structure
(let [updated (concat (take index structure) [v] (drop index structure))]
(if (string? structure)
(apply str updated)
updated
)
)))))

;; (temporarily) assign before-index-new to before-index so existing tests are exercised against it
;; to be removed before a final merge (wherein before-index-new is also renamed to before-index)
(def before-index before-index-new)

(defrichnav
^{:doc "Navigates to the index of the sequence if within 0 and size. Transforms move element
at that index to the new index, shifting other elements in the sequence."}
Expand Down
4 changes: 3 additions & 1 deletion test/com/rpl/specter/core_test.cljc
Expand Up @@ -1609,14 +1609,16 @@

(deftest before-index-test
(let [data [1 2 3]
datal '(1 2 3)]
datal '(1 2 3)
datastr "abcdef"]
(is (predand= vector? [:a 1 2 3] (setval (s/before-index 0) :a data)))
(is (predand= vector? [1 2 3] (setval (s/before-index 1) s/NONE data)))
(is (predand= vector? [1 :a 2 3] (setval (s/before-index 1) :a data)))
(is (predand= vector? [1 2 3 :a] (setval (s/before-index 3) :a data)))
(is (predand= list? '(:a 1 2 3) (setval (s/before-index 0) :a datal)))
(is (predand= list? '(1 :a 2 3) (setval (s/before-index 1) :a datal)))
(is (predand= list? '(1 2 3 :a) (setval (s/before-index 3) :a datal)))
(is (predand= string? "abcxdef" (setval (s/before-index 3) (char \x) datastr)))
))

(deftest index-nav-test
Expand Down

0 comments on commit 5e51ef1

Please sign in to comment.