FisherYates 셔플 基本思想(Knuth shuffle ):
n개 요소(인덱스 0..n-1)로 구성된 배열 a를 섞으려면:
i에 대해 n − 1에서 1 do까지
j ← 0 ≤ j ≤ i인 임의의 정수
a[j]와 a[i] 교환
JDK源代码如下:
/**
* 목록의 모든 요소를 목록의 임의의 새 위치로 이동합니다.
* 지정된 난수 생성기를 사용합니다.
*
* @param 목록
* 섞을 목록
* @param 랜덤
* 난수 생성기
*
* @throws UnsupportedOperationException
* 목록의 요소 교체가 지원되지 않는 경우
*/
@SuppressWarnings("선택 해제됨")
public static void shuffle(List<?> 목록, 무작위 무작위) {
if (!(RandomAccess 인스턴스 목록)) {
Object[] 배열 = list.toArray();
for (int i = array.length - 1; i > 0; i--) {
int 인덱스 = random.nextInt(i + 1);
if (색인 < 0) {
색인 = -색인;
}
객체 온도 = 배열[i];
배열[i] = 배열[인덱스];
배열[색인] = 임시;
}
int i = 0;
ListIterator<Object> it = (ListIterator<Object>) 목록
.listIterator();
동안(it.hasNext()) {
it.next();
it.set(배열[i++]);
}
} 또 다른 {
List<Object> rawList = (List<Object>) 목록;
for (int i = rawList.size() - 1; i > 0; i--) {
int 인덱스 = random.nextInt(i + 1);
if (색인 < 0) {
색인 = -색인;
}
rawList.set(index, rawList.set(i, rawList.get(index)));
}
}
}
공개 정적 무효 메인(최종 문자열 인수[]) {
개체 변경온도;
List<Integer> numList = new ArrayList<Integer>();
List<Integer> firstList = new ArrayList<Integer>();
List<Integer> secondList = new ArrayList<Integer>();
List<Integer> thirdList = new ArrayList<Integer>();
List<Integer> fourthList = new ArrayList<Integer>();
for (int i = 1; i <= 100000; i++) {
numList.add(i);
firstList.add(i);
secondList.add(i);
thirdList.add(i);
네 번째List.add(i);
}
// 첫 번째 섞기,changeTemp 사용
getStartTime();
int randInt = 0;
for (int i = 0, length = firstList.size(); i < length; i++) {
randInt = getRandom(i, firstList.size());
ChangeTemp = firstList.get(i);
firstList.set(i, firstList.get(randInt));
firstList.set(randInt, javaShuffle.temp);
}
getEndTime("첫 번째 셔플 런타임");
// 두 번째 셔플, 교환 목록
getStartTime();
for (int i = 0, length = secondList.size(); i < length; i++) {
randInt = getRandom(i, secondList.size());
secondList.set(i, secondList.set(randInt, secondList.get(i)));
}
getEndTime("두 번째 셔플 런타임");
// 세 번째 섞기, 무작위 정수 생성 변경
getStartTime();
Object[] tempArray = thirdList.toArray();
무작위 랜드 = 새로운 무작위();
정수 j = 0;
for (int i = tempArray.length - 1; i > 0; i--) {
j = rand.nextInt(i + 1);
thirdList.set(i, thirdList.set(j, thirdList.get(i)));
}
getEndTime("세 번째 셔플 런타임");
// 네 번째 셔플, Java 셔플 시뮬레이션
getStartTime();
무작위 무작위 = 새로운 무작위();
if (!(RandomAccess의 네 번째 목록 인스턴스)) {
Object[] array = fourthList.toArray();
for (int i = array.length - 1; i > 0; i--) {
int 인덱스 = random.nextInt(i + 1);
if (색인 < 0) {
색인 = -색인;
}
객체 온도 = 배열[i];
배열[i] = 배열[인덱스];
배열[색인] = 임시;
}
int i = 0;
ListIterator<Integer> it = (ListIterator<Integer>) fourthList.listIterator();
동안(it.hasNext()) {
it.next();
it.set((Integer) 배열[i++]);
}
} 또 다른 {
List<Integer> rawList = (List<Integer>) fourthList;
for (int i = rawList.size() - 1; i > 0; i--) {
int 인덱스 = random.nextInt(i + 1);
if (색인 < 0) {
색인 = -색인;
}
rawList.set(index, rawList.set(i, rawList.get(index)));
}
}
getEndTime("네 번째 셔플 실행 시간");
// 자바 셔플
getStartTime();
Collections.shuffle(numList);
getEndTime("java 셔플 런타임");
}
공개 정적 무효 교환(int a, int b) {
javaShuffle.temp = a;
a = b;
b = javaShuffle.temp;
}
public static int getRandom(final int low, final int high) {
return (int) (Math.random() * (높음 - 낮음) + 낮음);
}
공개 정적 무효 getStartTime() {
javaShuffle.start = System.nanoTime();
}
공개 정적 무효 getEndTime(최종 문자열 s) {
javaShuffle.end = System.nanoTime();
System.out.println(s + ": " + (javaShuffle.end - javaShuffle.start) + "ns");
}
}
如果数值较小,例如100000级别,则输流大概是:
첫 번째 셔플 실행 시간: 85029499ns
두 번째 셔플 실행 시간: 80909474ns
세 번째 셔플 실행 시간: 71543926ns
네 번째 셔플 런타임: 76520595ns
자바 셔플 런타임: 61027643ns
첫 번째 셔플 실행 시간: 82326239ns
두 번째 셔플 실행 시간: 78575611ns
세 번째 셔플 실행 시간: 95009632ns
네 번째 셔플 실행 시간: 105946897ns
자바 셔플 런타임: 90849302ns
첫 번째 셔플 실행 시간: 84539840ns
두 번째 셔플 실행 시간: 85965575ns
세 번째 셔플 실행 시간: 101814998ns
네 번째 셔플 실행 시간: 113309672ns
자바 셔플 런타임: 35089693ns
첫 번째 셔플 실행 시간: 87679863ns
두 번째 셔플 실행 시간: 79991814ns
세 번째 셔플 실행 시간: 73720515ns
네 번째 셔플 실행 시간: 78353061ns
자바 셔플 런타임: 64146465ns
첫 번째 셔플 실행 시간: 84314386ns
두 번째 셔플 실행 시간: 80074803ns
세 번째 셔플 실행 시간: 74001283ns
네 번째 셔플 실행 시간: 79931321ns
자바 셔플 런타임: 86427540ns
첫 번째 셔플 실행 시간: 84315523ns
두 번째 셔플 실행 시간: 81468386ns
세 번째 셔플 실행 시간: 75052284ns
네 번째 셔플 실행 시간: 79461407ns
자바 셔플 런타임: 66607729ns
如果是10000000级别,大概如下:
첫 번째 셔플 실행 시간: 2115703288ns
두 번째 셔플 실행 시간: 3114045871ns
세 번째 셔플 실행 시간: 4664426798ns
네 번째 셔플 실행 시간: 2962686695ns
Java 셔플 런타임: 3246883026ns 첫 번째 셔플 런타임: 2165398466ns
두 번째 셔플 실행 시간: 3129558913ns
세 번째 셔플 런타임: 4147859664ns
네 번째 셔플 실행 시간: 2911849942ns
자바 셔플 런타임: 4311703487ns 첫 번째 셔플 런타임: 2227462247ns
두 번째 셔플 실행 시간: 3279548770ns
세 번째 셔플 런타임: 4704344954ns
네 번째 셔플 실행 시간: 2942635980ns
Java 셔플 런타임: 3933172427ns 첫 번째 셔플 런타임: 2200158789ns
두 번째 셔플 실행 시간: 3172666791ns
세 번째 셔플 실행 시간: 4715631517ns
네 번째 셔플 실행 시간: 2950817535ns
Java 셔플 런타임: 3387417676ns 첫 번째 셔플 런타임: 2201124449ns
두 번째 셔플 실행 시간: 3203823874ns
세 번째 셔플 실행 시간: 4179926278ns
네 번째 셔플 실행 시간: 2913690411ns
자바 셔플 런타임: 3571313813ns 첫 번째 셔플 런타임: 2163053190ns
두 번째 셔플 실행 시간: 3073889926ns
세 번째 셔플 런타임: 4493831518ns
네 번째 셔플 실행 시간: 2852713887ns
자바 셔플 런타임: 3773602415ns
可以看流,第一种方法速島最快,而第四种最慢。java自带 shuffle速島也不理想。
이 앱은 Java를 사용하여 큰 규모의 논리적인 데이터베이스를 제공합니다.