Performance improvement (creating an arbitrary string of any length)

Create a random string of any specific length. I know this question has been asked many times, I wrote this code below, I just wanted to know if there is a better approach than the code below that I wrote? Or can we make more efficient code below?

public static void main(String[] args) { String s = randomString(25); System.out.println(s); } public static String randomString(final int length) { StringBuilder sb = new StringBuilder(); Random r = new Random(); String subset = "0123456789abcdefghijklmnopqrstuvwxyz"; for (int i = 0; i < length; i++) { int index = r.nextInt(subset.length()); char c = subset.charAt( index ); sb.append( c ); } return sb.toString(); } 
+4
source share
5 answers

Since you know the length ahead of time, configure StringBuilder with capacity:

StringBuilder sb = new StringBuilder (length);

This in itself eliminates unnecessary resizing of the internal array in StringBuilder.

In doing so, you are probably better off using the char [] array instead of StringBuilder and just represent the subset as char [].

 private static final char [] subset = "0123456789abcdefghijklmnopqrstuvwxyz".toCharArray(); char buf[] = new char[length]; for (int i=0;i<buf.length;i++) { int index = r.nextInt(subset.length); buf[i] = subset[index]; } return new String(buf); 

There are some subtle benefits there, avoiding some overhead calls to the charAt and append functions. We also eliminate some of the memory overhead and allocation time for StringBuilder. In general, if you know the size of the line you are building, it’s a bit more efficient to work directly with char arrays.

+2
source

First, it is likely that you probably do not need to improve the performance of this method. The likelihood that the method is not called often enough that its optimization will noticeably change the overall performance of the application. Before optimizing at this level, you must profile , otherwise you risk wasting time on things that do not matter.

Secondly, even if this is an effective optimization, you still need to profile the application to find out which optimizations work best ... and whether the optimization work really mattered.


If (hypothetically) I had to do this as quickly as possible, I would try this:

 private static final char[] subset = "0123456789abcdefghijklmnopqrstuvwxyz".toCharArray(); private static final Random prng = new Random(); ... public static String randomString(final int length) { char[] chars = new char[length]; final int subsetLength = subsetLength; for (int i = 0; i < length; i++) { int index = prng.nextInt(subsetLength); chars[i] = subset[index]; } return new String(chars); } 

In short:

  • Do not create a new instance of Random each time. This is probably the biggest optimization since instantiating usually involves a system call to get random seed.
  • Do not use StringBuilder when char[] working fine.
  • Avoid the (small) charAt overhead.
  • Raise one-time tasks from loops and method calls, where possible.

(Note that points 3. and 4. may not be practical, i.e. the JIT compiler can be smart enough to do the same optimizations for you ... if you just enable it.)

+3
source

Instead of working with String s, you can cast int to char and use it directly.

 // 36 total alpha-numeric characters int size = 36; for (int i=0; i<length; i++) { // num is an integer from 0-35 int num = r.nextInt(size); if (num < 26) { // Then we add a lowercase character sb.append((char)('a'+num)); } else { // then we add a digit 0-9 sb.append((char)('0'+(num-26))); } } 

Other possible optimizations:

  • Work with char[] with a fixed size, not with StringBuilder .
  • Define the subset string as static and final .

Of course, these optimizations are quite trivial and will not have much impact on your program in the context of this issue.


Edit:

If you need to create a random String with a fixed character set, then the approach described above will not work. You will have to work with a String containing characters, as in your post.

+1
source

Create a random string using only the specified string and length. you are using RandomStringUtils . if you want to create a random string RandomStringUtils # random for examples: the specified string and length is 25

 private static final SecureRandom RANDOM = new SecureRandom(); private static final char[] PASSWORD_CHARS=("0123456789abcdefghijklmnopqrstuvwxyz").toCharArray(); String passwd=RandomStringUtils.random(25, 0, PASSWORD_CHARS.length, false, false, PASSWORD_CHARS, RANDOM); 
+1
source

If you want to minimize calls to a random generator, you can create 5 characters from each random integer. But this implementation only works for your exact 36-character set: 0123456789abcdefghijklmnopqrstuvwxyz (see Integer.toString () Javadoc ). And it is unlikely that the ambiguity of this implementation can offset the performance gain.

 private static final int range = 36 * 36 * 36 * 36 * 36; // 36^5 is less than 2^31 private static Random rand = new Random(); private static String zeroes="00000"; public static String generate(int length) { StringBuilder sb = new StringBuilder(length+5); while (sb.length() < length) { String x = Integer.toString(rand.nextInt(range), 36); if(x.length()<5) sb.append(zeroes.substring(0, 5-x.length())); sb.append(x); } return sb.substring(0, length); } 

Zero addition ensures that the characters are uniformly random (without it, the character 0 will appear with a weaker frequency than others).

0
source

Source: https://habr.com/ru/post/1414563/


All Articles