繁体   English   中英

Dart:在多次调用的方法中编写嵌套函数是否有效

[英]Dart: Is it efficient to write nested functions in methods that are called several times

请考虑以下代码,

class A {
  foo() {
    int a = logicToGetA();

    int _bar() => someOtherLogic(a);

    // ..

    int b = _bar();

    // ..
  }
}

class B {
  int _bar(int a) => someOtherLogic(a);

  foo() {
    int a = logicToGetA();

    // ..

    int b = _bar(a);

    // ..
  }
}

main() {
  for (int i = 0; i < 1000000; i++) {
    A().foo();
  }
  for (int i = 0; i < 1000000; i++) {
    B().foo();
  }
}

说明:A 类的 bar() 嵌套在 foo() 内,B 类的 bar() 嵌套在 foo() 之外。 在第二种情况下, bar() 也可以作为静态方法。

我的疑问:如果 foo() 被多次调用,哪种方式更有效? 如果 A().foo() 被调用 1000000 次,A.foo.bar 会被重新定义很多次吗?

这取决于。

如果_bar函数可以在foo方法之外定义,那么我们可以假定它不引用foo方法的任何局部变量。 在这种情况下,编译器可以优化局部函数,使其与实例方法一样有效。 可能会,也可能不会,所以让我们检查一下。

请参阅: https : //dartpad.dev/4a53a91bf4e0006e4af4c8a598b68ee6 这是(尝试)编写的,以便编译器无法优化_someOtherLogic的调用。 我还尝试使调用成为静态方法(但随后必须将对象本身作为参数传递以访问flag的实例 getter)。

在 dartpad 中运行它给了我一组最终的结果

A: 918460 /ms
B: 798960 /ms
S: 918380 /ms

似乎 dart2js 使用本地函数比使用实例方法有效。 在 VM 上运行相同的代码会得到以下基准测试结果:

A: 625960.0 /ms
B: 723245.0 /ms
S: 625075.0 /ms

表明它的性能特征与 dart2js 完全相反。

dart2js 很可能在静态已知时内联_bar函数。 与 VM 相比,dart2js 编译器更倾向于内联。

总而言之,除非函数调用大量出现在实际程序的性能配置文件中,否则我不会开始担心这种差异。 如果你的程序的性能确实非常依赖于这一个函数调用,我可能会内联函数。 如果没有,请编写更具可读性和可维护性的内容,并且在您知道这很重要之前不要开始进行微优化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM