2
\$\begingroup\$

Can random string generation be faster in Java?

Here is my current code

import java.util.ArrayList;
import java.util.List;
public class FastestStringGeneration {
 private static final String ALPHA_NUMERIC_STRING = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
 private static final char[] ch = ALPHA_NUMERIC_STRING.toCharArray();
 private static final java.util.concurrent.ThreadLocalRandom random = java.util.concurrent.ThreadLocalRandom.current();
 public static void main(String[] java) {
 // warmup code
 String[] warmUp = new String[10000];
 for (int j=0; j<10000; j++){
 warmUp[j] = getAlphaNumeric(1024);
 }
 // real code begins
 int numIterations = 1000000;
 String[] randomStrings = new String[numIterations];
 long start = System.currentTimeMillis();
 for(int i=0; i<numIterations; i++){
 randomStrings[i] = getAlphaNumeric(1024);
 }
 System.out.println(System.currentTimeMillis()-start);
 System.out.println(randomStrings.length);
 }
 public static String getAlphaNumeric(int len) {
 char[] c = new char[len];
 for (int i = 0; i < len; i++) {
 c[i] = ch[random.nextInt(ch.length)];
 }
 return new String(c);
 }
}

The total time it takes to generate 1 million random strings is about ~ 5.9 seconds. Can it be faster?

I was using java.util.Random but when I changed to java.util.concurrent.ThreadLocalRandom according to comments below I got the most performance improvement!

asked Oct 23, 2018 at 8:41
\$\endgroup\$
22
  • \$\begingroup\$ I was trying in other languages and was able to accomplish in ~5 seconds. \$\endgroup\$ Commented Oct 23, 2018 at 8:45
  • \$\begingroup\$ I have this code in one of my application and that is where it spends the most time and yeah the faster implementation I found on other languages doesn't seem to use Random everytime instead some crazy bit shifting logic so I am wondering if anyone here could possibly come up with a solution \$\endgroup\$ Commented Oct 23, 2018 at 8:45
  • \$\begingroup\$ For sure you have a big overhead due to the initial size of your array that's is 10 (as default). I suggest to initialize it with new ArrayList<>(numIterations). More, you can avoid List<> and use String[]. This will cut overhead about list managment before alghorytm that can use bitwise operations to be faster. \$\endgroup\$ Commented Oct 23, 2018 at 8:48
  • 2
    \$\begingroup\$ use private static java.util.concurrent.ThreadLocalRandom random = ThreadLocalRandom.current(); instead of java.util.Random. The java.util.Random uses locks to be thread-safe, it slows down execution. \$\endgroup\$ Commented Oct 23, 2018 at 15:00
  • 1
    \$\begingroup\$ Welp. No. I thought that was you. Ehm. They should write an answer as well then 😅 \$\endgroup\$ Commented Oct 23, 2018 at 18:18

1 Answer 1

1
\$\begingroup\$

If the length is always identical you can save 1000000 calls to new().

Because new String(char[]) uses Arrays.copyOf(), you don't need a new char[] in every loop.

private static int ourlen = 1024;
private static char[] chars = new char[ourlen];
public static String getAlphaNumeric() {
 for (int i = 0; i < ourlen; i++) {
 chars[i] = ch[random.nextInt(ch.length)];
 }
 return new String(c);
}
answered Oct 24, 2018 at 11:54
\$\endgroup\$
1
  • \$\begingroup\$ True. 300ms gain! Tells me Java object creation is awesome! \$\endgroup\$ Commented Oct 24, 2018 at 14:53

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.