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

欢迎!请参阅关于页面了解有关如何使用本网站的更多信息。

0票数
变换器
对基本重构的改进,去除 let 表达式,每个迭代只需要单个计数器检查,从而提高了 25% 的性能。使用补丁,最后迭代只需进行两次检查...


;; master
(quick-bench (into [] (take 1000) (range 2000)))
警告:最后一次 GC 需要了 34.82584189073624 % 的运行时间
评估计数:6 次样本中的 13050 次。
             执行时间平均值:46.921254 微秒
    执行时间标准差:1.904733 微秒
   执行时间下四分位数:45.124921 微秒(2.5%)
   执行时间上四分位数:49.427201 微秒(97.5%)
                   使用的开销:2.367243 纳秒

;; w/ patch
(quick-bench (into [] (take 1000) (range 2000)))
警告:最后一次 GC 需要了 34.74448252054369 % 的运行时间
评估计数:6 次样本中的 18102 次。
             执行时间平均值:34.301193 微秒
    执行时间标准差:1.714105 微秒
   执行时间下四分位数:32.341349 微秒(2.5%)
   执行时间上四分位数:37.046851 微秒(97.5%)
                   使用的开销:2.367243 纳秒

6 答案

0票数

评论者:toxi

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

0票数

评论者:alexmiller

从一个表面的检查来看,我看到了对 pos? 和 neg? 的检查,这两个都排除了 0,这让我对此分支有所怀疑。这实际上可能没问题,但我需要更仔细地阅读。

0票数

评论者:toxi

嗨Alex,尝试运行测试...据我所知,它仍然像预期一样工作:在(take 0)或(take -1)的情况下,pos?检查失败,但我们必须确保不要调用rf那次迭代。在所有其他(take n)的情况下,除了最后一次迭代外(会导致单次多余的neg?调用),只会执行pos?检查。当前的路径/实现在所有迭代中都会进行两次检查,因此速度较慢。

0票数

评论者:alexmiller

只有当传递的n <= 0时,才会击中neg?案例,所以我认为这是正确的。但是,您可能需要考虑以某种不同方式处理这个特定的案例——例如,它可以完全从transducer函数中提取出来,并作为一个完全独立的transducer函数创建。我不确定这值得做,但这是一个想法。

0票数
_由:toxi_发表的评论

好主意,Alex!这个第二补丁删除了{{neg?}}检查,并为n <= 0的情况添加了快速跳转transducer。这也让它更快了一些


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


(现在比原始版本快约35%)
0票数
...