9

我是 Clojure 和函数式编程的新手。我想创建一个包含 100,000 个键的列表,格式为:XXXXX-XXXXX-XXXXX-XXXXX-XXXXX

我做这样的事情:

(defn get-key [chunk-size, key-length] 
 (apply str 
  (flatten
   (interpose "-" 
    (partition chunk-size 
     (take key-length 
      (repeatedly #(rand-nth "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"))))))))

(defn dump-keys [n, chunk-size, key-length] 
 (with-open [wrt (io/writer "keys.txt")]
  (doseq [i (range n)]
   (.write wrt (str (get-key chunk-size key-length) "\n")))))

哪个生产

KYFL0-7YO6J-30XMV-ZIGE7-MK009
MNQZH-K7L8I-35C0K-7DS7Q-OTZWI
MVB9D-GHME9-IMGCL-YPAKX-4YZVD
... etc

但是,它需要大约 5 秒,与类似的命令式算法相比,这相对较长。

什么被认为是做我想做的事情的惯用(和快速)方式?

4

2 回答 2

5

为了获得最大速度,我建议采用以下技术:

  • 使用预分配的构造键(char-array 29)
  • 用于aset在数组中的每个位置设置字符
  • 使用randomz获得非常快的随机数(比 快约 150% java.util.Random
  • 查找字符.charAt,例如(.charAt "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" (int (Rand/r 36)))
  • 用于dotimes您的循环 - 这通常比映射/任何带有序列的东西更快

如果你做了以上所有,你应该得到非常高效的代码,可能和你用纯 Java 编写它的速度一样快。

于 2013-05-25T10:54:10.190 回答
0

如果您想要最大的性能,我认为您最好的办法就是用 Java 编写这个函数,然后从 Clojure 中调用它。或者如果你想留在 Clojure 中,你可以使用aset来填充 Javachar数组,并使用(String. array)将它们转换为字符串。我不认为这真的是“惯用的” Clojure,但它会很快。

于 2013-05-25T10:45:50.817 回答