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ố u32và some_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