【问题标题】:What does 'Zero Cost Abstraction' mean?“零成本抽象”是什么意思?
【发布时间】:2021-09-14 13:06:46
【问题描述】:

我在探索 Rust 时遇到了这个术语。

我看到了关于这个的不同类型的解释,但仍然不太明白。

The Embedded Rust Book中,它说

类型状态也是零成本抽象的一个很好的例子

  • 将某些行为移动到编译时执行或分析的能力。

这些类型状态不包含实际数据,而是用作 标记。

由于它们不包含数据,因此它们在 运行时内存:

这是否意味着运行时更快,因为运行时没有内存?

如果有人能以通俗易懂的方式解释它,不胜感激。

【问题讨论】:

  • 零成本抽象不会使任何事情变得更快,而是它们(希望)使运行时完全相同就像您编写较低级别的未抽象版本一样(通常以牺牲为代价)编译时间)。这个想法通常是添加一个便利抽象层,但不会产生任何运行时损失。

标签: rust


【解决方案1】:

零成本抽象意味着添加更高级别的编程概念,如泛型、集合等不会带来运行时成本,只有编译器时间成本(代码编译会更慢)。零成本抽象上的任何操作都与您使用较低级别的编程概念(for 循环、计数器、ifs 等)手动编写匹配功能一样快。

【讨论】:

    【解决方案2】:

    零成本抽象是在执行速度或内存使用方面不承担运行时成本的抽象。

    相比之下,虚方法是昂贵抽象的一个很好的例子:在许多 OO 语言中,方法调用者的类型是在运行时确定的,这需要维护一个查找表(运行时内存使用)和然后使用运行时类型实际执行查找(每个方法调用的运行时开销,可能至少是额外的指针取消引用)以确定调用哪个版本的方法。另一个很好的例子是垃圾收集:作为回报,您不必担心因 GC 暂停而支付的内存分配细节。

    Rust 虽然主要尝试实现零成本抽象:那些让你有蛋糕也能吃的东西。编译器可以安全且正确地转换为不承担额外间接/内存使用的形式。事实上,我知道的唯一一件事(如果我错了,有知识渊博的人会纠正我)你在 Rust 运行时真正付出的代价就是边界检查。

    【讨论】:

    • Rust 具有提供运行时虚函数行为的特征,例如(参见例如this
    • @rubenvb 我没有意识到那些是在运行时调度的,我认为接收器的类型必须在编译时知道。
    • 好吧,从某种意义上说,Rust 似乎是“聪明的”,因为它会在可能的情况下“去虚拟化”特征的使用(至少这就是我戴着 C++ 眼镜阅读this blog post 的方式)。我认为归根结底是 Rust 为静态和动态调度提供了统一的语法。
    • Traits 可以在运行时或编译时调度。如果你有一个struct Foo: Bar 和一个变量let foo = Foo{},那么从Bar 调用一个方法将在编译时调度(零成本)。但是,如果您的变量是 Bar 引用:let bar = &foo as &Bar,那么调度将在运行时使用与大多数 OO 语言相同的查找表来完成(除非优化器能够返回到 Foo 类型,这一些面向对象的语言也可以)。
    猜你喜欢
    • 2011-06-13
    • 1970-01-01
    • 2011-04-07
    • 2014-08-27
    • 1970-01-01
    • 2017-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多