为啥我的传感器功能比使用 ->> 运算符慢?

Posted

技术标签:

【中文标题】为啥我的传感器功能比使用 ->> 运算符慢?【英文标题】:Why is my transducer function slower than using ->> operator?为什么我的传感器功能比使用 ->> 运算符慢? 【发布时间】:2018-07-20 07:01:02 【问题描述】:

在解决 Hackkerank (https://www.hackerrank.com/challenges/string-compression/problem) 的问题时,我编写了 2 个使用和不使用传感器的实现。

我希望转换器实现比函数链接运算符->> 更快。不幸的是,根据我的迷你基准测试,链接运算符的性能比传感器高 2.5 倍。

我在想,我应该尽可能使用传感器。还是我没有正确理解传感器的概念?

时间:

“经过的时间:0.844459 毫秒”

“经过的时间:2.697836 毫秒”

代码:

(defn string-compression-2
  [s]
  (->> s
       (partition-by identity)
       (mapcat #(if (> (count %) 1)
               (list (first %) (count %))
               (list (first %))))
       (apply str)))

(def xform-str-compr
  (comp (partition-by identity)
        (mapcat #(if (> (count %) 1)
                (list (first %) (count %))
                (list (first %))))))

(defn string-compression-3
  [s]
  (transduce xform-str-compr str s))

(time (string-compression-2 "aaabccdddd"))
(time (string-compression-3 "aaabccdddd"))

【问题讨论】:

我已经意识到,虽然在 repl 中运行函数的性能或多或少是相等的(换能器解决方案快 0.001)导致 ~0.1 毫秒 也许我应该发布另一个问题,但为什么 repl 优于.clj 文件运行时间? 运行一项测试时噪音太大。循环运行相同的测试 N 次并计算总时间。 答:因为有transducer的版本在重复使用str,作为reducer函数。 @Vincent 花了我一段时间才得到它:D 写在答案下的对话中完成:sweat_smile 【参考方案1】:

根据Criterium,传感器版本似乎确实更快:

(crit/quick-bench (string-compression-2 "aaabccdddd"))
             Execution time mean : 6.150477 µs
    Execution time std-deviation : 246.740784 ns
   Execution time lower quantile : 5.769961 µs ( 2.5%)
   Execution time upper quantile : 6.398563 µs (97.5%)
                   Overhead used : 1.620718 ns

(crit/quick-bench (string-compression-3 "aaabccdddd"))
             Execution time mean : 2.533919 µs
    Execution time std-deviation : 157.594154 ns
   Execution time lower quantile : 2.341610 µs ( 2.5%)
   Execution time upper quantile : 2.704182 µs (97.5%)
               Overhead used : 1.620718 ns

正如 coredump 评论的那样,一个样本量不足以说明一种方法是否通常比另一种方法更快。

【讨论】:

那么我应该始终使用函数组合和转换器而不是函数链吗? 如果性能是您最关心的问题,您只需要进行基准测试(使用一系列输入),看看哪种方法表现更好。我不会说总是使用传感器;在许多情况下,它们具有性能优势,但它们也具有与性能无关的优势。 “这取决于”:) 但是我的功能不完全一样吧?我一直在观看 Rich 的传感器视频,他在 step function 的帮助下展示了地图的抽象。所以在我的例子中,step 函数是str,这意味着我将对所有中间结果调用 str 函数,对吗?因此->> 的示例将只调用函数str 一次,这肯定会更快,对吧?我的意思是,使用str 作为步进函数并不聪明,对吧?您对此有何看法? FWIW,xforms 库有一个 net,cgrand.xforms.rfs/str 减少函数,它使用字符串生成器来避免这个问题。

以上是关于为啥我的传感器功能比使用 ->> 运算符慢?的主要内容,如果未能解决你的问题,请参考以下文章

为啥乘法、加法的霓虹内在函数比运算符慢?

为啥“OR”运算符比 oracle 中的 union 慢

单片机的温度传感器DS18B20测出来的温度可靠么?它测得的温度比我的酒精温度计高1.2度比指针式温度计高1.3

为啥sql数据库的表用VBA导到EXCEL中的速度比EXCEL的数据导入功能慢

为啥要使用 Go 语言?Go 语言的优势在哪里?

为啥 SSE scalar sqrt(x) 比 rsqrt(x) * x 慢?