"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > 간단한 작업을 위해 스트림이 기존 컬렉션보다 항상 느린가요?

간단한 작업을 위해 스트림이 기존 컬렉션보다 항상 느린가요?

2024-11-08에 게시됨
검색:906

Are Streams Always Slower Than Traditional Collections for Simple Operations?

Java 8 스트림 성능과 비교. 기존 컬렉션

최근 Java 8을 사용하여 Stream API의 성능을 클래식 컬렉션과 비교하는 비공식 벤치마크를 수행했습니다. 테스트에는 정수 목록 필터링, 짝수의 제곱근 추출 및 결과를 Double 목록에 저장하는 작업이 포함됩니다. 그러나 귀하는 테스트의 타당성에 의문을 제기하고 있으며 실제 성능에 미치는 영향을 명확히 하고 싶어합니다.

벤치마크 테스트 평가

스트림을 나타내는 초기 결과 컬렉션보다 속도가 느려 우려가 제기되었습니다. 보다 신뢰할 수 있는 평가를 위해서는 잠재적인 오류를 해결하고 공정한 테스트를 수행하는 것이 필수적입니다. 다음은 몇 가지 고려 사항입니다.

  • LinkedList 사용: LinkedList는 효율적인 무작위 액세스가 부족하므로 결과 목록에 대한 최적의 선택이 아닙니다. 대신 ArrayList를 사용해 보세요.
  • 벤치마크 방법론: 수동 벤치마킹은 부정확할 수 있습니다. 보다 정확하고 안정적인 측정을 제공하려면 JMH(Java Microbenchmarking Harness)와 같은 벤치마킹 프레임워크를 활용하세요.

적절한 벤치마킹 결과

이러한 권장 사항에 따라 JMH를 활용한 성능 평가 및 향상된 벤치마킹 전략:

@OutputTimeUnit(TimeUnit.NANOSECONDS)
@BenchmarkMode(Mode.AverageTime)
@OperationsPerInvocation(StreamVsVanilla.N)
public class StreamVsVanilla {
    public static final int N = 10000;

    static List sourceList = new ArrayList();
    static {
        for (int i = 0; i  vanilla() {
        List result = new ArrayList(sourceList.size() / 2   1);
        for (Integer i : sourceList) {
            if (i % 2 == 0){
                result.add(Math.sqrt(i));
            }
        }
        return result;
    }

    @Benchmark
    public List stream() {
        return sourceList.stream()
                .filter(i -> i % 2 == 0)
                .map(Math::sqrt)
                .collect(Collectors.toCollection(
                    () -> new ArrayList(sourceList.size() / 2   1)));
    }
}

결과:

Benchmark                   Mode   Samples         Mean   Mean error    Units
StreamVsVanilla.stream      avgt        10       17.588        0.230    ns/op
StreamVsVanilla.vanilla     avgt        10       10.796        0.063    ns/op

발견

초기 결과와는 달리 JMH 벤치마크는 기존 수집 방식이 기존 수집 방식보다 훨씬 빠르다는 것을 분명히 보여줍니다. 이 특정 스트림 접근 방식 시나리오.

결론

이러한 향상된 벤치마킹 결과를 바탕으로 다음과 같은 결론을 내릴 수 있습니다.

  • 스트림은 본질적으로 컬렉션보다 느리지 않습니다. 그러나 간단한 필터링 및 매핑 작업과 같은 특정 사용 사례에서는 오버헤드가 이점보다 클 수 있습니다.
  • 스트림은 코드 단순성과 유지 관리성 측면에서 상당한 이점을 제공합니다. 데이터 처리 파이프라인을 단순화하고 상용구 코드를 줄입니다.
  • 성능이 중요한 코드 경로의 경우 항상 철저한 벤치마킹을 수행하고 애플리케이션의 특정 요구 사항을 고려하는 것이 좋습니다.
최신 튜토리얼 더>

부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.

Copyright© 2022 湘ICP备2022001581号-3