2024年Clojure状态调查!中分享您的想法。

欢迎!有关如何工作的更多信息,请参阅关于页面。

0
Clojure

take-nth transducer在每次索引时调用rem,与零?测试相比,成本较高。由于步长是固定的,它可以直接从N开始倒数。

5 答案

0

评论者:[email protected]

附上补丁。它在像

(time (transduce (take-nth 13) + (range 1e7)))

0
这样的简单测试中快约25%

评论者:[email protected]

我没有担心(take-nth 0)的情况,但我的补丁确实给出了不同的结果。当前的实现会得到一个除零错误(来自rem)。我的补丁版本只在第一次返回第一个元素。常规集合版本会返回一个包含第一个元素的无穷序列。我怀疑没有人会期待从0的情况得到合理的答案,所以我没有尝试对它做特别处理。

0

评论者:michaelblume

不错 =)

我认为变压器的版本应该尽可能地与收集版本相匹配,但我想没有实际的方法可以编写一个将有限序列转换为无限序列的变压器,所以在这方面运气不佳。

也许在做这件事的时候,我们应该将变压器和收集的桂序都更改为抛零?

0
评论由 reborg 提出

垃圾输入/垃圾输出的情况,但rem也有责任


用户=> (take-nth 2.5 (range 10))
(0 3 6 9)
用户=> (sequence (take-nth 2.5) (range 10))
(0 5)


Steve(CLJ-1665-faster-take-nth-transducer-without-rem.patch)提出的补丁只是缺少将上述内容转换为int的转换来解决问题


(defn take-nth [n]
  (fn [rf]
    (let [n (int n)
          iv (volatile! 1)]
      (fn
        ([] (rf))
        ([result] (rf result))
        ([result input]
         (let [i (vswap! iv dec)]
           (if (zero? i)
             (do (vreset! iv n)
                 (rf result input))
             result)))))))


0
参考:[https://clojure.atlassian.net/browse/CLJ-1665](https://clojure.atlassian.net/browse/CLJ-1665)(由[email protected]报告)
欢迎来到Clojure Q&A,您可以在此处提问,并获得来自Clojure社区成员的回答。
...