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

欢迎!请查阅关于页面以获取更多关于此如何运作的信息。

0
转换器
一个基本的重构,移除了let形式,并对每个迭代仅需要单个计数器检查,从而将性能提高了25%。使用补丁,最后一次迭代仅需要2次检查(如果计数器参数为 <= 0)...


;;主分支
(quick-bench (into [] (take 1000) (range 2000)))
WARNING: 最终GC必须使用34.82584189073624 %的运行时间
评估计数:在6个样本中为2175次调用中的13050次。
             执行时间平均值:46.921254 µs
    执行时间标准差:1.904733 µs
   执行时间下四分位数:45.124921 µs(2.5%)
   执行时间上四分位数:49.427201 µs(97.5%)
                开销使用:2.367243 ns

;; 有补丁
(quick-bench (into [] (take 1000) (range 2000)))
WARNING: 最终GC必须使用34.74448252054369 %的运行时间
评估计数:在6个样本中为3017次调用中的18102次。
             执行时间平均值:34.301193 µs
    执行时间标准差:1.714105 µs
   执行时间下四分位数:32.341349 µs(2.5%)
   执行时间上四分位数:37.046851 µs(97.5%)
                开销使用:2.367243 ns

6 个答案

0

评论由:toxi

提议的补丁,所有现有测试都通过

0

评论由:alexmiller

经过初步浏览,我发现检查pos?和neg?,它们都排除了0,这让我对此分支有所怀疑。这实际上可能没问题,但我会更仔细地阅读。

0
by

评论由:toxi

嗨,Alex,尝试运行测试...据我所知,它仍然按广告工作:对于(take 0)或(take -1),pos?检查会失败,但我们必须确保不为此迭代调用rf。对于所有其他(take n)情况,只执行pos?检查(除了最后一个迭代,这会导致一个多余的neg?调用)。当前的路径/实现总是对所有迭代执行2次检查,因此运行速度较慢。

0
by

评论由:alexmiller

只有当传递给take的参数n <= 0时,才会遇到neg?情况,所以我认为这是正确的。但是,您可以考虑用不同的方式处理这种情况 - 例如,可以将这部分完全从transducer函数中提取出来,并作为完全独立的另一个transducer函数创建。我不确定这是否值得做,但这是一个想法。

0
by
_由:toxi_作出评论

好主意,Alex!这个第二个补丁删除了neg?检查,并为n <= 0的情况添加了一个快速退出的transducer。这使得它略微更快


(quick-bench (into [] (take 1000) (range 2000)))
评估次数:在6个3395次调用中为20370。
             执行时间平均值:30.302673 µs


(现在比原始代码快约35%)
0
by
...