• Streams em Java executam por padrão de forma sequencial.
  • Com muitos dados (ex: milhões de usuários), o processamento sequencial pode ser lento.

Para paralelizar esse processo, podemos usar:

  • parallelStream() para coleções.
  • .parallel() em qualquer Stream.

  • A API de Fork/Join é utilizada internamente, mas sem precisar configurar nada manualmente.

  • O resultado é o mesmo da versão sequencial.

Cuidado: o paralelismo tem overhead e só compensa quando:
O input de dados é grande.
A operação é pesada (como acesso a disco ou rede).

Exemplo 1 – Usuários com mais de 100 pontos (sequencial e paralelo)
▶️ Versão sequencial:

List filtradosOrdenados = usuarios.stream()
    .filter(u -> u.getPontos() > 100)
    .sorted(Comparator.comparing(Usuario::getNome))
    .collect(Collectors.toList());

▶️ Versão paralela:

List filtradosOrdenados = usuarios.parallelStream()
    .filter(u -> u.getPontos() > 100)
    .sorted(Comparator.comparing(Usuario::getNome))
    .collect(Collectors.toList());

🧪 O que é Benchmark?
Benchmark (ou microbenchmark, no contexto do livro) é uma medida de desempenho. Em programação, fazer benchmark significa avaliar o tempo que um código leva para executar ou o consumo de recursos (como memória e CPU) durante sua execução.

✅ Para que serve um benchmark?
Comparar duas formas diferentes de fazer a mesma coisa (ex: stream sequencial vs. paralelo).
Avaliar o impacto de uma otimização.
Entender gargalos de performance.
Decidir se vale a pena paralelizar uma operação.

🧪 Exemplo 2 – Benchmark com LongStream de 1 bilhão

▶️ Versão paralela (mais rápida para grandes volumes):

long sum = LongStream.range(0, 1_000_000_000)
    .parallel()
    .filter(x -> x % 2 == 0)
    .sum();

System.out.println(sum);

▶️ Versão sequencial:

long sum = LongStream.range(0, 1_000_000_000)
    .filter(x -> x % 2 == 0)
    .sum();

System.out.println(sum);

⚠️ Dicas importantes

Use parallel() ou parallelStream() somente quando:

  • A operação justifica o custo do paralelismo.
  • Há grande volume de dados.
  • Faça testes de performance antes de decidir. Teste seu caso específico (microbenchmarks podem enganar).

Avalie o tamanho do input e o custo das operações.
Use parallelStream() ou parallel() apenas quando houver ganho real.

🔹 Exemplo completo: ExemploParallelStream