Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fastest way to generate random strings

Tags:

clojure

I'm new to Clojure and functional programming. I'd like to create a list of 100,000 keys in the format: XXXXX-XXXXX-XXXXX-XXXXX-XXXXX

I do something like this:

(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")))))

Which produces

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

However, it takes around 5 seconds, which is comparatively long compared to a similar imperative-style algorithm.

What's considered an idiomatic (and quick) way to do what I'm trying to do?

like image 771
cyrus Avatar asked May 25 '13 10:05

cyrus


1 Answers

To get maximum speed for this, I would suggest the following techniques:

  • Construct the keys using a pre-allocated (char-array 29)
  • Use aset to set the character at each position in the array
  • Use randomz to get very fast random numbers (about 150% faster than java.util.Random)
  • Look up the character with .charAt, e.g. something like (.charAt "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" (int (Rand/r 36)))
  • Use dotimes for your loop - this is generally faster than mapping / anything with sequences

If you do all the above, you should get very efficient code, probably as fast as you could write it in pure Java.

like image 162
mikera Avatar answered Sep 30 '22 05:09

mikera