Clojure 中的快速随机字符串生成器
Fast random string generator in Clojure
我想知道是否有一种方法可以在 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
让我回答我自己的问题:
(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 中生成固定长度的随机字符串。
快速搜索结果:
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
让我回答我自己的问题:
(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)))