List에서 큰 값/작은 상위 n개를 추출하는 처리(top-k selection)는 Guva로 해보세요.
개시하다
이어 "리스트와 배열 등에 대해 이른바 자바로 탑-k selection을 효율적으로 구현하는 방법에 대해 1년에 2∼3차례 정도 빈도가 고민된다"며 "무슨 좋은 탑-k selection 시행이 있나.
(도쿄도/34세/남성)
나는 프로그램을 쓰는 과정에서 여러 가지 장소에서 반드시 top-k selection을 해야 하는 상황을 자주 만날 수 있다고 생각한다.물론 RDBMS를 이용하면 ORDER BY sort_column LIMIT k
쉽게 탑-k selection이 가능하지만, RDBMS 외에 탑-k selection을 해야 하는 상황(1년에 2∼3번이면 개인 차이가 크다)은 인생에서 1∼2번 겪을 수 있다.
그러나 최근에는 Guava: Google Core Libraries for Java에 이것top-k selection 설치이 있다는 것을 알았기 때문에 이 실시가 도대체 사용할 수 있고 성능이 얼마나 높은지 궁금해서 기준을 만들어 봤다.그렇다면 성능은 어떨까.
Guva의 top-k selection 설치
이번에 기준 대상인 구바의 top-k selection 알고리즘은 다음과 같이 시행됐다.
이번에 기준 대상인 구바의 top-k selection 알고리즘은 다음과 같이 시행됐다.
k
를 비교하고, k
List의 절반보다 큰 시간Arrays.sort()
(즉TimSort))을, top-kk
Integer.MAX_VALUE / 2
이상이면 Collections.sort()
(이것도 TimSort)top-kIterator
에 대해 다음과 같은 알고리즘으로 top-k를 구한다.k * 2
크기 버퍼 및 Arrays.sort()
기준 조건
처리량 비교
Collections.sort()
및 Ordering#leastOf()
Collections.sort()
TimSortCollections.sort()
top-k selection을 실시할 때 정렬 후 top-k 부품만 추출하고 새로운 Arrey List를 생성할 때까지 처리를 측정 대상으로 한다k
(선택한 개수)는List 사이즈에 대한 비례에 따라 계산한다import com.google.common.collect.Ordering;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.infra.Blackhole;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
@State(Scope.Benchmark)
public class GuavaOrderingBenchmark {
@Param({"0.05", "0.1", "0.2", "0.4", "0.8"})
public double sortingRatio;
@Param({"20", "320", "5120"})
public int size;
private int k;
private List<Double> data;
@Setup
public void prepare() {
k = (int) (size * sortingRatio);
Random r = new Random(12345L);
data = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
data.add(r.nextDouble());
}
}
@Benchmark
public void collectionsSort(Blackhole bh) {
bh.consume(leastK(data, k));
}
@Benchmark
public void guavaOrdering(Blackhole bh) {
bh.consume(Ordering.natural().leastOf(data, k));
}
private List<Double> leastK(List<Double> data, int k) {
Collections.sort(data);
return new ArrayList<>(data.subList(0, k));
}
}
기준 결과
도표로 기준 결과를 봅시다.처리량을 나타내며 로드가 길수록 성능이 좋다는 뜻이다.
어떤 결과를 보든지 간단히Collections.sort()
정렬한 후 top-k selection을 하는 것이 좋다.결과가 너무 뜻밖이어서 나는 매우 놀랐다.구바는 무슨.
총결산
예상한 결과(최고는 구바)를 얻지 못했고, 과도한 구바 참패 상황으로 추가로 기준 획득의 기력을 잃었다.아마 초대형 리스트의 경우 아주 작은k
아래 구바 설치를 이용하면 성능이 더 좋지 않을까.아마
Reference
이 문제에 관하여(List에서 큰 값/작은 상위 n개를 추출하는 처리(top-k selection)는 Guva로 해보세요.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/komiya_atsushi/items/1f0a84cba591502c468a
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
예상한 결과(최고는 구바)를 얻지 못했고, 과도한 구바 참패 상황으로 추가로 기준 획득의 기력을 잃었다.아마 초대형 리스트의 경우 아주 작은
k
아래 구바 설치를 이용하면 성능이 더 좋지 않을까.아마
Reference
이 문제에 관하여(List에서 큰 값/작은 상위 n개를 추출하는 처리(top-k selection)는 Guva로 해보세요.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/komiya_atsushi/items/1f0a84cba591502c468a텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)