[英]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.