Tại sao Vec :: keep chạy chậm hơn sau khi cập nhật lên Rust 1.38.0?


8

Sau khi cập nhật Rust lên phiên bản 1.38.0 từ 1.36.0, tôi nhận thấy rằng chương trình của tôi chạy chậm hơn - khoảng 50%.

Sử dụng perf, tôi phát hiện ra rằng một nửa thời gian của chương trình được dành alloc::vec::Vec<T>::retaincho phiên bản mới. Trong phiên bản cũ hơn, chức năng này thậm chí không hiển thị. Tại sao sẽ retainmất nhiều thời gian hơn trong 1.38.0?

Cuộc gọi đến retainđược thực hiện như thế này:

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

deadlinelà một hằng số u32some_veclà a Vec<u32>.

Tôi chạy chương trình mà không có retaincuộc gọi trong cả hai phiên bản. Trong trường hợp này, trung bình 1.38.0 vẫn chậm hơn, nhưng chỉ bằng ~ 10% thay vì> 50% được thấy trước đó.

Để tóm tắt lại những gì đã xảy ra trong các bài kiểm tra:

Phiên bản 1.36.0

  • với retain: ~ 18 giây
  • không có retain: ~ 11 giây

Phiên bản 1.38.0

  • với retain: ~ 28 giây
  • không có retain: ~ 12 giây

Để biết ví dụ có thể lặp lại, bạn có thể thử:

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);
}

Với cargo +1.36.0 run --releasevà sau đó cargo +1.38.0 run --release.

Với ví dụ nhỏ này, tôi đã nhận được:

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

$ cargo +1.38.0 run --release
Program took: 8.293383522s

3
Tôi tin rằng điều này nên được báo cáo cho nhóm Rust lang .
Hội trường Peter

Cảm ơn đã cải thiện câu hỏi của bạn để đáp ứng với phản hồi. Bạn thực sự biến nó xung quanh! Tôi hy vọng bạn nhận được một câu trả lời.
trentcl

2
Tôi đã đào một ít: 1.37.0 nhanh như 1.36.0; đêm thì chậm. MIR được tạo ra là 1.37 và 1.38 giống với tôi nếu bạn bỏ qua các nhận xét và thứ tự các hàm tương đối, hàm ý: Rustc đã thay đổi số / thứ tự / loại LLVM hoặc phiên bản LLVM được sử dụng bởi Rustc thay đổi giữa 1.37 và 1.38, trong trường hợp này là hồi quy LLVM cũng như hồi quy Rustc. Tôi không biết làm thế nào để biết, thật không may.
trentcl

Đây là báo cáo lỗi mà
@Miguel

Câu trả lời:


2

Nói chung, Rust.godbolt.org rất hữu ích để kiểm tra chất lượng mã được tạo (nhưng đừng quên thêm cờ tối ưu hóa!)

Trong trường hợp mã của bạn được tạo cho retainrõ ràng đã thay đổi xấu hơn: https://rust.godbolt.org/z/ZhVCDg

Vì vậy, bạn nên báo cáo điều đó với Rust như một hồi quy hiệu suất.


1
Tôi đã báo cáo nó bị rỉ sét như @Peter Hall cũng đề xuất.
Miguel

4
Dành cho những người tò mò: github.com/rust-lang/rust/issues/65970
mcarton
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.