执行此操作后:
use std::sync::Arc;
use std::time::Instant;
fn main() {
let cap = 100000000;
let b0 = vec![0; cap];
let now = Instant::now();
Arc::new(b0);
println!("T0: {:?}", now.elapsed());
let c0 = vec![0; cap];
let _ = c0.clone(); // <- this makes it slow
let now = Instant::now();
Arc::new(c0);
println!("T1: {:?}", now.elapsed());
}
Run Code Online (Sandbox Code Playgroud)
结果是:T0:5.971µs T1:26.69574ms
如果我们之前克隆 c0,为什么第二个 Arc::new 很慢?
编辑:
我用以下方法测试了它:
T1 的时间随向量大小线性增加。
请注意,您不是在测量 所花费的时间Arc::new,而是测量 Arc 被放下时所花费的时间(因为您没有将其分配给任何东西)。
另请注意,根据您的系统,此行:
let b0 = vec![0; cap];
Run Code Online (Sandbox Code Playgroud)
可能不分配任何物理内存:它只能分配虚拟空间,物理内存在第一次访问时被分配和归零。cachegrind 证实了这一点,在克隆缓冲区之前几乎没有缓存未命中。
克隆载体有两个副作用:
Arc,使用以下代码将解除分配移出测量的时间,时间更快更接近:
use std::sync::Arc;
use std::time::Instant;
fn main() {
let cap = 1000000000;
let b0 = vec![0; cap];
let now = Instant::now();
let a = Arc::new(b0);
println!("T0: {:?}", now.elapsed());
drop (a);
let c0 = vec![0; cap];
let _ = c0.clone(); // <- this makes it slow
let now2 = Instant::now();
let a = Arc::new(c0);
println!("T1: {:?}", now2.elapsed());
drop (a);
}
Run Code Online (Sandbox Code Playgroud)
第二个Arc::new仍然较慢,但可以通过 cachegrind 报告的 3 个额外的 L3 缓存未命中来解释差异。
| 归档时间: |
|
| 查看次数: |
241 次 |
| 最近记录: |