2024年Clojure调查问卷!分享您的想法。

欢迎!请查阅关于页面以了解更多有关该功能的信息。

0
转换器
对现有代码进行重构,移除let形式,仅在每次迭代中进行单个计数器检查,可提升25%的性能。补丁中,最后迭代只需要进行2次检查(假设计数器参数<=0)...


;; master
(quick-bench (into [] (take 1000) (range 2000)))
警告:最后的GC操作耗费了运行时的34.82584189073624 %
评估次数:在6个样本中,共2175次调用。
             平均执行时间:46.921254 µs
    执行时间标准差:1.904733 µs
   执行时间较低四分位数:45.124921 µs ( 2.5%)
   执行时间较高四分位数:49.427201 µs (97.5%)
                   _overhead_used_ : 2.367243 ns

;; w/ patch
(quick-bench (into [] (take 1000) (range 2000)))
警告:最后的GC操作耗费了运行时的34.74448252054369 %
评估次数:在6个样本中,共3017次调用。
             平均执行时间:34.301193 µs
    执行时间标准差:1.714105 µs
   执行时间较低四分位数:32.341349 µs ( 2.5%)
   执行时间较高四分位数:37.046851 µs (97.5%)
                   _overhead_used_ : 2.367243 ns

6 答案

0

评论者:toxi

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

0

评论者:alexmiller

表面浏览后,我看到pos?和neg?的检查,都排除了0,这让我对这个分支有所保留。这可能实际上是好的,但我需要更仔细地阅读。

0
by

评论者:toxi

嗨Alex,尝试运行测试...据我所知,一切仍按预期工作:对于(take 0)或(take -1),位置检查失败,但我们必须确保不调用rf того迭代。对于所有其他(take n)示例,除了最后一个迭代(引起单个多余的neg?调用)之外,只在位置检查被执行。当前路径/实现总是对所有迭代执行两次检查,因此要慢得多。

0
by

评论者:alexmiller

仅在传递n <= 0到take时,neg?情况才会被命中,因此我认为这是正确的。然而,你可能考虑以某种不同的方式处理该特定情况 - 例如,它可以从transducer函数中提取出来,并完全作为单独的transducer函数创建。我不确定这是否值得做,但这是一种想法。

0
by
_由:toxi_ 发布的评论

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


(quick-bench (into [] (take 1000) (range 2000)))
评估次数:20370次,6个样本,每次3395调用。
             平均运行时间:30.302673微秒


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