Clojure Performance For Expensive Algorithms

后端 未结 2 642
滥情空心
滥情空心 2020-12-29 11:13

I have implemented an algorithm to calculate the longest contiguous common subsequence (not to be confused with longest common subsequence, though not important for

2条回答
  •  生来不讨喜
    2020-12-29 11:34

    Here are a couple improvements:

    1. No advantage to fancy type hinting, just use ^objects
    2. aset-int is deprecated I believe -- just plain old aget is faster, by about 3x overall it seems

    Beyond that (and the long type hint on the recur mentioned above), I don't see any obvious ways to improve further.

    (defn lcs
      [^objects a1 ^objects a2]
      (let [a1-len (alength a1)
            a2-len (alength a2)
            prev (int-array (inc a2-len))
            curr (int-array (inc a2-len))]
        (loop [i 0 max-len 0 prev prev curr curr]
          (if (< i a1-len)
            (recur (inc i)
                   (long (loop [j 0 max-len max-len]
                     (if (< j a2-len)
                       (if (= (aget a1 i) (aget a2 j))
                         (let [match-len (inc (aget prev j))]
                           (do
                             (aset curr (inc j) match-len)
                             (recur (inc j) (max max-len match-len))))
                         (do
                           (aset curr (inc j) 0)
                           (recur (inc j) max-len)))
                       max-len)))
                   curr
                   prev)
            max-len))))
    #'user/lcs
    user> (time (lcs a1 a2))
    "Elapsed time: 3862.211 msecs"
    

提交回复
热议问题