当前位置: 首页 > 知识库问答 >
问题:

Arc::new()使用克隆向量时速度很慢

夔修伟
2023-03-14

执行此操作后:

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

结果是:T0:5.971µs T1:26.69574ms

为什么第二个新的Arc::慢,如果我们克隆c0之前?

编辑:

我用以下方法测试了它:

    < li>Windows 10,rust 1.44.1调试版 < li>Linux,rust 1.47-夜间发行版 < li>Linux,rust 1.18 < li>MacOS,rust 1 . 44 . 0-夜间发布

T1的时间随向量大小线性增加。

共有1个答案

贝研
2023-03-14

请注意,您不是在测量<code>圆弧::new</code>所花费的时间,而是在测量圆弧下降时所花的时间(因为您没有将其分配给任何对象)。

还请注意,根据您的系统,这一行:

let b0 = vec![0; cap];

不能分配任何物理内存:它只能分配虚拟空间,物理内存在首次访问时被分配并归零。缓存网格证实了这一点,在克隆缓冲区之前,缓存网格显示几乎没有缓存未命中。

克隆载体有两个副作用:

  • 它会导致映射物理内存,这意味着在丢弃 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);
}

第二个 Arc::new 仍然较慢,但这种差异可以通过缓存网格报告的 3 个额外的 L3 缓存未命中来解释。

 类似资料:
  • 问题内容: 我有一个PostgreSQL函数,可以将查询结果返回到pgadmin结果网格中。在内部,这是一个简单的函数,使用a连接到另一个数据库并返回查询,以便我可以简单地运行 它的运行就像基本的表查询一样。 问题是当我使用该子句时。因此,我想运行以下查询,但它要花很多时间: 我怎样才能加快速度?有什么比这种情况下的子句快的吗? 问题答案: 不是表-可能是一些存储过程,因此查询并不是很简单。您需要

  • 问题内容: 很久很久以前有一堂课: 在对象中,我们有: 而Cloneable接口是: 我应该如何克隆呢? 问题答案: 我认为当前的绿色答案不好 ,为什么您会问? 它添加了很多代码 它要求您列出所有要复制的字段并执行此操作 当使用clone()时,这对列表不起作用(这是HashMap的clone()所说的:返回此HashMap实例的浅表副本:键和值本身不会被克隆。)因此您最终需要手动进行操作(这使得

  • 本文向大家介绍JavaScript浅层克隆与深度克隆示例详解,包括了JavaScript浅层克隆与深度克隆示例详解的使用技巧和注意事项,需要的朋友参考一下 1 相关知识点 浅克隆就是将栈内存中的引用复制一份,赋给一个新的变量,本质上两个指向堆内存中的同一地址,内容也相同,其中一个变化另一个内容也会变化。 深克隆就是创建一个新的空对象,开辟一块内存,然后将原对象中的数据全部复制过去,完全切断两个对象

  • deepClone 对象深度克隆 注意 由于JS对象包括的范围非常广,加上ES6又有众多的新特性,很难、也没必要做到囊括所有的类型和情况,这里说的"对象",指的是普通的对象,不包括修改对象原型链, 或者为"Function","Promise"等的情况,请留意。 场景: 我们平时可能会遇到需要通过console.log打印一个对象,至执行打印的时刻,此对象为空,后面的逻辑中对此对象进行了修改赋值,

  • 应用克隆 (用于已有服务,需要在另一个业务线下创建一个同样的服务,不需要重新创建) 服务/环境克隆(菜单栏:工具集->服务/环境克隆) 点击菜单栏,在项目列表中筛选您要克隆的项目,然后点击 克隆 ,弹框中选择您要克隆到哪个业务线。 选择目录空间,系统为在目标空间下生成该应用所需要的所有类型资源和Jenkins Job。

  • 受这个问题的启发。我创建了一个小型基准测试程序来比较原型、二进制格式和Json。NET。基准测试本身是一个基于https://github.com/sidshetye/SerializersCompare的小型控制台。随意添加/改进,向组合中添加一个新的序列化程序非常简单。无论如何,我的结果是: 免责声明: > 以上结果来自Windows虚拟机-与裸机操作系统相比,非常小间隔的秒表/计时器值可能不