【问题标题】:Metaprogramming performance in DartDart 中的元编程性能
【发布时间】:2015-05-11 19:59:28
【问题描述】:

在 Dart 中使用运算符重载时,操作函数是在编译时解析,还是在运行时解析,或者其他什么?

在什么情况下 vm 或 dart2js 能够绕过类似这样的东西:

function add(left, right) {
    if (isPrimitive(left) && isPrimitive(right)) {
        return left + right;
    } else if (left.hasOverload("+")) {
        return left.plus(right);
    } else if (left.hasReverseOverload("+")) {
        return right.plus(left);
    } else {
        throw new Error("Cannot add objects");
    }
}

在 dart 中,编译时的 a + b 可能会更改为 add(a,b)。这将是运行时检查,出于显而易见的原因,我担心它的性能。所以基本上,什么时候在 Dart 中使用运行时检查?

【问题讨论】:

  • 我不确定这在 Dart 中是否容易区分,因为 Dart 在运行时编译。据我所知,如果它们被频繁调用并且它有足够的知识,Dart 会优化这些东西。 Dart 在运行时丢弃类型注释,这使得这更难分辨。
  • 我想我应该改写这个问题,因为飞镖可能会在中间做点什么。

标签: dart operator-overloading metaprogramming vm-implementation dart2js


【解决方案1】:

Dart 中的运算符与对象上的其他方法没有什么不同。 语言规范允许在运行时解析方法,而且大部分都会这样。

但是,如果从代码中非常清楚哪种值在哪里流动,则智能编译器可能能够识别在编译时调用的函数。对于何时发生这种情况没有硬性规定,因为这取决于编译器使用的分析效果如何,这可能会每天都在变化(通常会变得更好)。 dart2js 编译器可以进行各种分析和优化,而 VM JIT 编译器必须非常快。在后一种情况下,优化也将在运行时发生,此时优化重新编译知道实际到达函数的类型。

所以,Dart 编译器绝对可以像您展示的那样进行优化。 是否以及何时这样做,一般都不能说。

总而言之,在您真正确定 + 调用是一个瓶颈之前不要担心。

【讨论】:

  • Dart 的真理对任何编译器都是如此:“你得到的东西,无论是字节码、目标码还是源代码,”都承诺在功能上是等价的 与您输入的内容相同,但不完全相同。 “运算符重载”绝对是你可以期待 Dart 做很多摆弄的事情,因为目标语言不直接支持这个概念。就性能而言,最好的建议是:“不要猜测,不要试图预测。配置文件。” 尽量避免编写可能是热点的东西,但要找出是否它们是:分析(生成的)代码。
猜你喜欢
  • 1970-01-01
  • 2011-08-03
  • 2015-01-28
  • 2014-11-27
  • 1970-01-01
  • 1970-01-01
  • 2020-04-19
  • 1970-01-01
  • 2011-12-04
相关资源
最近更新 更多