Por que o Vec :: retém a execução mais lenta após a atualização para o Rust 1.38.0?

8

Após atualizar o Rust para a versão 1.38.0 de 1.36.0, notei que meu programa fica mais lento - em cerca de 50%.

Usando perf, descobri que metade do tempo do programa é gasto na alloc::vec::Vec<T>::retainnova versão. Na versão mais antiga, essa função nem aparece. Por que retaindemoraria tanto mais tempo na versão 1.38.0?

A chamada para retainé feita assim:

some_vec.retain(|&x| x < DEADLINE);

deadlineé uma constante u32e some_vecé a Vec<u32>.

Eu executei o programa sem as retainchamadas nas duas versões. Nesse caso, o 1.38.0 ainda era mais lento, em média, mas apenas em ~ 10% em vez dos> 50% vistos anteriormente.

Para recapitular o que aconteceu nos testes:

Versão 1.36.0

  • com retain: ~ 18seg
  • sem retain: ~ 11seg

Versão 1.38.0

  • com retain: ~ 28seg
  • sem retain: ~ 12seg

Para um exemplo reproduzível, você pode tentar:

use std::time::Instant;

fn main() {
    let start = Instant::now();
    let mut my_vec: Vec<u32>;
    for _ in 0..100_000 {
        my_vec = (0..10_000).collect();
        my_vec.retain(|&x| x < 9000);
        my_vec.retain(|&x| x < 8000);
        my_vec.retain(|&x| x < 7000);
        my_vec.retain(|&x| x < 6000);
        my_vec.retain(|&x| x < 5000);
        my_vec.retain(|&x| (x < 5) & (x > 2));
    }
    let duration = start.elapsed();
    println!("Program took: {:?}", duration);
}

Com cargo +1.36.0 run --releasee então cargo +1.38.0 run --release.

Para este pequeno exemplo, obtive:

$ cargo +1.36.0 run --release
Program took: 4.624297719s

$ cargo +1.38.0 run --release
Program took: 8.293383522s
Miguel
fonte
3
Acredito que isso deve ser relatado à equipe do Rust lang .
Peter Hall
Obrigado por melhorar sua pergunta em resposta ao feedback. Você realmente mudou! Espero que você obtenha uma resposta.
trentcl
2
Eu fiz uma pequena escavação: 1.37.0 é rápido como 1.36.0; todas as noites é lento. O MIR gerado de 1,37 e 1,38 parece o mesmo para mim se você desconsiderar os comentários e a ordem relativa de funções, o que implica: rustc alterou o número / ordem / tipo de passes LLVM ou a versão do LLVM usada por rustc mudou entre 1,37 e 1,38, caso em que esta é uma regressão LLVM, bem como uma regressão rustc. Não sei dizer qual, infelizmente.
trentcl
Aqui é o relatório de bug que @Miguel arquivado
harmic

Respostas: