가장 높은 평가를받은 답변은 Java 8을 사용하는 것이 가장 좋은 답변이지만 동시에 성능면에서는 절대적으로 최악입니다. 성능이 나쁜 나쁜 응용 프로그램을 원한다면 계속 사용하십시오. 고유 한 개인 이름 세트를 추출하기위한 간단한 요구 사항은 단지 "For-Each"및 "Set"에 의해 달성됩니다. 목록이 10보다 크면 상황이 더욱 악화됩니다.
다음과 같이 20 개의 오브젝트가 있다고 가정하십시오.
public static final List<SimpleEvent> testList = Arrays.asList(
new SimpleEvent("Tom"), new SimpleEvent("Dick"),new SimpleEvent("Harry"),new SimpleEvent("Tom"),
new SimpleEvent("Dick"),new SimpleEvent("Huckle"),new SimpleEvent("Berry"),new SimpleEvent("Tom"),
new SimpleEvent("Dick"),new SimpleEvent("Moses"),new SimpleEvent("Chiku"),new SimpleEvent("Cherry"),
new SimpleEvent("Roses"),new SimpleEvent("Moses"),new SimpleEvent("Chiku"),new SimpleEvent("gotya"),
new SimpleEvent("Gotye"),new SimpleEvent("Nibble"),new SimpleEvent("Berry"),new SimpleEvent("Jibble"));
당신이 반대하는 곳 SimpleEvent
은 다음과 같습니다.
public class SimpleEvent {
private String name;
private String type;
public SimpleEvent(String name) {
this.name = name;
this.type = "type_"+name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
그리고 테스트하려면 다음 과 같은 JMH 코드 가 있습니다 ( 허용 된 답변에 언급 된 동일한 distinctByKey 술어를 사용하십시오 )
@Benchmark
@OutputTimeUnit(TimeUnit.SECONDS)
public void aStreamBasedUniqueSet(Blackhole blackhole) throws Exception{
Set<String> uniqueNames = testList
.stream()
.filter(distinctByKey(SimpleEvent::getName))
.map(SimpleEvent::getName)
.collect(Collectors.toSet());
blackhole.consume(uniqueNames);
}
@Benchmark
@OutputTimeUnit(TimeUnit.SECONDS)
public void aForEachBasedUniqueSet(Blackhole blackhole) throws Exception{
Set<String> uniqueNames = new HashSet<>();
for (SimpleEvent event : testList) {
uniqueNames.add(event.getName());
}
blackhole.consume(uniqueNames);
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(MyBenchmark.class.getSimpleName())
.forks(1)
.mode(Mode.Throughput)
.warmupBatchSize(3)
.warmupIterations(3)
.measurementIterations(3)
.build();
new Runner(opt).run();
}
그러면 다음 과 같은 벤치 마크 결과가 나타납니다.
Benchmark Mode Samples Score Score error Units
c.s.MyBenchmark.aForEachBasedUniqueSet thrpt 3 2635199.952 1663320.718 ops/s
c.s.MyBenchmark.aStreamBasedUniqueSet thrpt 3 729134.695 895825.697 ops/s
보시다시피 간단한 For-Each 는 Java 8 Stream에 비해 처리량이 3 배 향상되고 오류 점수는 적습니다.
높은 처리량, 더 나은 성능
Function<? super T, ?>
아니라고 생각Function<? super T, Object>
합니다. 또한 정렬 된 병렬 스트림의 경우이 솔루션은 (일반과 달리distinct()
) 추출 될 객체를 보장하지 않습니다 . 또한 순차 스트림의 경우 CHM 사용에 대한 추가 오버 헤드가 있습니다 (@nosid 솔루션에는 없음). 마지막으로이 솔루션은filter
JavaDoc에 명시된대로 술어가 상태 비 저장이어야하는 메소드 계약을 위반합니다 . 그럼에도 불구하고 공감했다.