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

欢迎!请查阅 关于 页面,获取有关此内容的一些更多信息。

0
Clojure

take-nth 转换器对每个索引调用 rem,与使用零测试相比,成本较高。它可以直接以 N 为步数递减。

5 个答案

0

[email protected] 发表的评论

提供的补丁。在类似以下简单测试中提高了大约 25% 的性能:

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

0

[email protected] 发表的评论

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

0

由 michaelblume 发表的评论

好棒 =)

我认为变送器版本应该尽可能接近收集版本,但是我认为实际上没有一种方法可以编写一个将有限序列转换为无限序列的变送器,所以在这方面没有运气。

也许当我们做这件事的时候,我们应该将变送器和收集数组的基数都改为抛零?

0
by
_评论者:reborg_

GIGO案例,但rem也负有责任


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


Steve的补丁(CLJ-1665-faster-take-nth-transducer-without-rem.patch)只是缺少一个转换为整数的cast来解决上述问题。


(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
by
欢迎来到Clojure问答社区,您可以在这里提问并从Clojure社区的成员那里获得答案。
...