I ran into a situation in my application where I wanted to take a set-
difference between a small set and a large set.  In this circumstance,
clojure.set/difference is needlessly slow.  Because of this, in
general, a sequence of n clojure.set operations may run in O(n^2) time
when O(n) is easily achievable.  Here's the basic idea:

(defn difference2 "Like difference, but fast for big s2 and small
s1" [s1 s2]
  (reduce (fn [result item] (if (contains? s2 item) (disj result item)
result))
          s1 s1))

(defn fast-difference "Like difference, but faster." [s1 s2]
  (let [c1 (int (count s1))
        c2 (int (count s2))]
    (if (< c1 c2)
        (difference2 s1 s2)
      (clojure.set/difference s1 s2))))

user> (let [small-set (hash-set 1), big-set (set (range 10000))]
        (doseq [fn [clojure.set/difference difference2 fast-difference]
                [s1 s2] [[small-set big-set] [big-set small-set]]]
          (time (dotimes [_ 1000] (fn s1 s2)))))

"Elapsed time: 3995.249 msecs"  ; (set/difference small big)
"Elapsed time: 3.358 msecs"     ; (set/difference big small)
"Elapsed time: 1.91 msecs"      ; (difference2 small big)
"Elapsed time: 4935.183 msecs"  ; (difference2 big small)
"Elapsed time: 3.088 msecs"     ; (fast-difference small big)
"Elapsed time: 3.401 msecs"     ; (fast-difference big small)

For the commutative operations (union and intersection), I suppose you
could argue that the user should know how the operations work and put
the arguments in the right (fast) order -- but sometimes, that
information will only be known at runtime.  Overall, the possibility
of a big O improvement for a small constant penalty seems worth it to
me.

Questions or comments?  Any objections/support for me adding this as
an issue?

Thanks,
Jason


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to