【问题标题】:Fast random string generator in ClojureClojure 中的快速随机字符串生成器
【发布时间】:2020-09-23 19:09:03
【问题描述】:

我想知道是否有办法在 Clojure 中生成固定长度的随机字符串。

快速搜索结果:

https://gist.github.com/rboyd/5053955

(defn rand-str [len]
  (apply str (take len (repeatedly #(char (+ (rand 26) 65))))))

在查看了 VisualVM CPU 配置文件数据后,我意识到这消耗了大量的 CPU:

我决定重写它,类似于我以前使用的 Java 函数:

(defn rand-str2-slow
  ^String [^Long len]
  (let [leftLimit 97
        rightLimit 122
        random (Random.)
        stringBuilder (StringBuilder. len)
        diff (- rightLimit leftLimit)]
    (dotimes [_ len]
      (let [ch (char (.intValue (+ leftLimit (* (.nextFloat random) (+ diff 1)))))]
        (.append stringBuilder ch)))
        (.toString stringBuilder)))

这导致代码更慢,但堆栈跟踪的深度要小得多:

我注意到它做了很多 Reflector.getMethods()。有没有办法输入提示函数来避免这种情况?

更新1:

相关微基准:

rand-str

(with-progress-reporting (quick-bench (rand-str 5000) :verbose))

      Execution time sample mean : 1.483232 ms
             Execution time mean : 1.483547 ms
Execution time sample std-deviation : 31.161960 µs
    Execution time std-deviation : 31.651732 µs
   Execution time lower quantile : 1.441678 ms ( 2.5%)
   Execution time upper quantile : 1.531289 ms (97.5%)
                   Overhead used : 14.598226 ns

rand-str2-慢

(with-progress-reporting (quick-bench (rand-str2-slow 5000) :verbose))

      Execution time sample mean : 17.637256 ms
             Execution time mean : 17.647974 ms
Execution time sample std-deviation : 523.527242 µs
    Execution time std-deviation : 528.559280 µs
   Execution time lower quantile : 17.322583 ms ( 2.5%)
   Execution time upper quantile : 18.522246 ms (97.5%)
                   Overhead used : 14.598226 ns

rand-str2(快速)

(with-progress-reporting (quick-bench (rand-str2 5000) :verbose))

      Execution time sample mean : 84.362974 µs
             Execution time mean : 84.355379 µs
Execution time sample std-deviation : 3.496944 µs
    Execution time std-deviation : 3.674542 µs
   Execution time lower quantile : 80.911920 µs ( 2.5%)
   Execution time upper quantile : 89.264431 µs (97.5%)
                   Overhead used : 14.598226 ns

【问题讨论】:

    标签: java performance clojure


    【解决方案1】:

    让我回答我自己的问题:

    (defn rand-str2
      ^String [^Long len]
      (let [leftLimit 97
            rightLimit 122
            random (Random.)
            stringBuilder (StringBuilder. len)
            diff (- rightLimit leftLimit)]
        (dotimes [_ len]
          (let [ch (char (.intValue ^Double (+ leftLimit (* (.nextFloat ^Random random) (+ diff 1)))))]
            (.append ^StringBuilder stringBuilder ch)))
            (.toString ^StringBuilder stringBuilder)))
    

    【讨论】:

    • 是的,避免装箱/拆箱和类型提示通常是要走的路。可惜第一版不能再优化了。
    • 是的,惯用的 Clojure 非常慢。这就是价格。
    猜你喜欢
    • 1970-01-01
    • 2015-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-25
    • 2011-05-20
    相关资源
    最近更新 更多