Java 8 Stream Performance vs. Coleções tradicionais
Recentemente, você se aventurou no Java 8 e conduziu um benchmark informal para comparar o desempenho de sua API Stream com as coleções clássicas. Seu teste envolve filtrar uma lista de números inteiros, extrair a raiz quadrada de números pares e armazenar os resultados em uma lista Dupla. No entanto, você está questionando a validade do seu teste e está ansioso para esclarecer as verdadeiras implicações de desempenho.
Avaliando o teste de referência
Seus resultados iniciais, que indicaram fluxos ser mais lento do que as cobranças, suscitou preocupações. Para garantir uma avaliação mais confiável, é essencial abordar possíveis erros e realizar um teste justo. Aqui estão algumas considerações:
Resultados:
Média de amostras do modo de referência Unidades de erro médio StreamVsVanilla.stream média 10 17,588 0,230 ns/op StreamVsVanilla.vanilla avgt 10 10,796 0,063 ns/op@OutputTimeUnit(TimeUnit.NANOSECONDS) @BenchmarkMode(Mode.AverageTime) @OperationsPerInvocation(StreamVsVanilla.N) public class StreamVsVanilla { public static final int N = 10000; static ListsourceList = 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))); } }
Findings
Ao contrário dos resultados iniciais, o benchmark JMH mostra claramente que a abordagem de coleta tradicional é significativamente mais rápida do que a abordagem de fluxo neste particular cenário.@OutputTimeUnit(TimeUnit.NANOSECONDS) @BenchmarkMode(Mode.AverageTime) @OperationsPerInvocation(StreamVsVanilla.N) public class StreamVsVanilla { public static final int N = 10000; static ListsourceList = 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))); } }
Conclusão
Com base nesses melhores resultados de benchmarking, podemos concluir que:Streams não são inerentemente mais lentos que coleções. No entanto, sua sobrecarga pode superar os benefícios em certos casos de uso, como operações simples de filtragem e mapeamento.Streams oferecem vantagens significativas em termos de simplicidade e capacidade de manutenção do código. Eles simplificam os pipelines de processamento de dados e reduzem o código clichê.
Para caminhos de código críticos para o desempenho, é sempre aconselhável realizar benchmarking completo e considerar os requisitos específicos do seu aplicativo.
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3