Skip to content

Instantly share code, notes, and snippets.

@joinr
Last active December 8, 2022 21:29
Show Gist options
  • Save joinr/bac1ac20350e11bc5b11ef4bbbaacb05 to your computer and use it in GitHub Desktop.
Save joinr/bac1ac20350e11bc5b11ef4bbbaacb05 to your computer and use it in GitHub Desktop.
exploration of the fastest way to compute diff using the tech stack.
;;https://www.reddit.com/r/Clojure/comments/zd36cb/faster_way_to_calculate_difference_of_vector/
(set! *unchecked-math* :warn-on-boxed)
(set! *warn-on-reflection* true)
(require '[tech.v3.dataset :as ds])
(require '[tech.v3.datatype :as dtype])
(require '[tech.v3.datatype.functional :as func])
(require '[criterium.core :as c])
(def some-data (ds/->dataset {:x [12 123 23 45 45 1 123 5 1]}))
(def big-data (ds/->dataset {:x (range 100000)}))
(def x (some-data :x)) ;;this a tech.ml.dataset Column.
(def big-x (big-data :x)) ;;same.
;;OP's implementation.
(defn diff [x] (map - (rest x) (drop-last x)))
;;benchmarks take the following form to force computation:
;;(c/quick-bench (vec (some-function x)))
;;(c/quick-bench (vec (some-function big-x)))
;;x: Execution time mean : 2.654048 ╡s
;;big-x: Execution time mean : 352.714899 ╡s
(defn fast-diff [xs]
(let [ls (dtype/sub-buffer xs 1)
rs (dtype/sub-buffer xs 0 (unchecked-dec (count xs)))]
(func/- ls rs)))
;;x: Execution time mean : 4.351775 ╡s
;;big-x: Execution time mean : 62.084662 ╡s
(defn faster-diff [col]
(dtype/make-reader :float64 (dec (count col)) (- ^double (col idx) ^double (col (inc idx)))))
;;x: Execution time mean : 734.416214 ns
;;big-x: Execution time mean : 60.963510 ╡s
(defn fastest-diff [col]
(let [col (dtype/->reader col :float64)]
(dtype/make-reader :float64 (dec (count col))
(- (.readDouble col idx)
(.readDouble col (inc idx))))))
;;Execution time mean : 916.364478 ns
;;Execution time mean : 60.593710 ╡s
(defn faster-diff-long [col]
(dtype/make-reader :int64 (dec (count col)) (- ^long (col idx) ^long (col (inc idx)))))
;;x: Execution time mean : 741.795139 ns
;;big-x: Execution time mean : 59.298311 ╡s
(defn fastest-diff-long [col]
(let [col (dtype/->reader col :int64)]
(dtype/make-reader :int64 (dec (count col))
(- (.readLong col idx)
(.readLong col (inc idx))))))
;;x: Execution time mean : 857.461193 ns
;;big-x: Execution time mean : 51.817547 ╡s
(defn array-diff [col]
(let [^doubles xs (double-array col)
res (double-array (dec (count col)))]
(dotimes [idx (count res)]
(aset res idx (- (aget xs (inc idx)) (aget xs idx))))
res))
;;x: Execution time mean : 832.903379 ns ;;vec
;;big-x: Execution time mean : 48.173555 ╡s ;;vec
;;x: Execution time mean : 414.885086 ns ;;no vec
;;big-x: Execution time mean : 29.290519 ╡s ;;no vec
(ns neandertest.core
(:require [uncomplicate.neanderthal
[core :as n]
[native :refer [dv]]
[random :refer [rand-normal! rand-uniform! rng-state]] ]
[criterium.core :as c]))
(def x (dv 12 123 23 45 45 1 123 5 1))
(def big-x (apply dv (range 1000)))
(defn diff [origin]
(let [k (unchecked-dec (n/dim origin))
l (n/subvector origin 0 k)
r (n/subvector origin 1 k)]
(n/axpy -1 l r)))
;;x: Execution time mean : 582ns
;;big-x: Execution time mean : 1.550939 µs
(defn diff! [origin]
(let [k (dec (n/dim origin))
l (n/subvector origin 0 k)
r (n/copy origin 1 k)]
(n/axpy! -1 l r)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment