2014-05-01 6 views
5

Moim celem jest wygenerowanie pseudolosowego ciągu znaków składającego się z 500000 znaków z małego wyboru znaków. To jest moja pętla do dodawania znaków String:Jak mogę zoptymalizować mój kod do generowania ciągów pseudolosowych dla dużej szybkości w Javie?

String alphabet="ABCD"; 
Random r = new Random(); 
for (int i = 0; i < 500000; i++) { 
    this.setCode((this.getCode() == null ? "" : this.getCode()) 
    alphabet.charAt(r.nextInt(alphabet.length()))); 
} 

Unsurprisingly ten jest bardzo powolny, więc szukam sposobów na to, aby wykonać ewentualne> najmniej powolny <.

Odpowiedz

4

Skorzystaj z StringBuilder, aby skonstruować ciąg znaków. Przeznaczyć 500000 znaków z góry, aby ją przyspieszyć trochę:

StringBuilder sb = new StringBuilder(500000); 
for (int i = 0; i < 500000; i++) { 
    sb.append(alphabet.charAt(r.nextInt(alphabet.length()))); 
} 
String res = sb.toString(); 
+0

To zrobiło niesamowitą różnicę, nie wymagając dodatkowej biblioteki. –

+0

W zależności od tego, jakiego rodzaju implementacji używasz do losowania, możesz być w stanie uzyskać lepsze i szybsze wyniki, jeśli nie zależy Ci na synchronizacji, a prędkość jest naprawdę czynnikiem, możesz zamiast tego używać MersenneTwisterFast.java. http://cs.gmu.edu/~sean/research/mersenne/MersenneTwisterFast.java –

+2

Nie używaj 'StringBuilder', jeśli znasz długość z góry, zamiast tego użyj nowego' char [50000] '. Użyj [ThreadLocalRandom] (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadLocalRandom.html), aby uzyskać jeszcze większą szybkość. – maaartinus

2

Jeśli jesteś gotów do korzystania z biblioteki innej firmy, sprawdź Gmin Apache RandomStringUtils.

int count = 500000; 
String alphabet = "ABCD"; 
String randomString = RandomStringUtils.random(count, alphabet); 

na moim laptopie (MacBook Pro), zajęło około 20ms, aby wygenerować ciąg 500K.

1

Korzystanie z StringBuilder pomoże, ale jeszcze bardziej, jeśli zadeklarujesz początkowy rozmiar jako faktyczną długość oczekiwanego wyniku. W ten sposób unika się zmiany rozmiaru wewnętrznego macierzy StringBuilder w środowisku wykonawczym. Również dostęp do tablicy znaków String bezpośrednio jest nieco szybszy niż przy użyciu charAt(int) na String - odniesienie jest bezpośrednie zamiast tworzenia odwołania do metody do tablicy.

public static String getRandomString(String characterSet){ 
    final char[] chars = characterSet.toCharArray(); 
    final int size = 500000; 
    StringBuilder sb = new StringBuilder(size); 
    Random rand = new Random(); 
    for(int i=0;i<size;i++){ 
     sb.append(chars[rand.nextInt(chars.length)]); 
    } 
    return sb.toString(); 
}