@pragma("vm:prefer-inline") 在 Flutter 中意味着什么?

Vil*_*Lin 25 dart flutter

我在框架中看到了很多代码,如下所示。注释有什么@pragma作用?

@pragma("vm:entry-point", "call")
@pragma("vm:entry-point", "set")
@pragma("vm:entry-point", "get")
@pragma("vm:prefer-inline")`
......
Run Code Online (Sandbox Code Playgroud)

Mab*_*ten 28

对于cfr的一般含义@pragma上面NKSM的回答。

我将引用两个重要的具体用例:

  • @pragma('vm:prefer-inline')内联函数

    (我的意思是编译时内联,它与作为closure/lambda同义词的“内联函数”无关,有时会这样做)

    该注解类似于Kotlin中的inline关键字

  • @pragma("vm:entry-point")标记一个函数(或其他实体,如类)以向编译器指示它将从本机代码中使用。如果没有这个注释,dart 编译器可能会删除未使用的函数、内联它们、缩小名称等,并且本机代码将无法调用它。

    一个非常好的文档(比平常写得更清楚)entry-point是https://github.com/dart-lang/sdk/blob/master/runtime/docs/compiler/aot/entry_point_pragma.md

如果您想在 dart 中使用内联进行第一次测试,我建议您使用dart2js进行编译,它会输出相当可读的 JavaScript 代码(至少直到您将收缩级别提高到默认级别以上为止;并且只有在最小程序中可读性才明显不错) 。然而,dart/js 中的内联需要稍微不同的 @pragma 注释:@pragma ('dart2js: tryInline')。

关于 dart 中内联的有趣讨论可以在 dart-lang 问题 #40522 - Annotation for method inlined中找到

总的来说,我建议Mraleph 博客。他的最新文章是关于 dart 的基准测试,并且还展示了@pragma(vm:entry-point). Mraleph 是一名 Dart Sdk 开发人员(他也是上面引用的官方文档的作者),它是有关 Dart VM 相关主题的非常宝贵的资源。


NKS*_*KSM 8

Flutter 使用Dart编程语言。

Pragma类充当Dart 编程各个方面的指导工具。

在Dart 程序中,我们可以在声明上使用 pragma 注释来为工具提供提示。这些提示是不同工具以自己的方式解释的建议。工具可以自主选择它们理解哪些提示、如何解释它们以及在代码中应用它们的位置。

这是Flutter和Dart@pragma("vm:prefer-inline")中使用的特定提示,用于影响Dart 虚拟机(VM) 的优化过程。该编译指示向Dart VM建议,在优化期间应优先考虑内联(或内联扩展)某些函数。内联是一种优化技术,将被调用函数的代码直接插入到调用函数中,从而消除了函数调用的开销。

用 标记函数@pragma("vm:prefer-inline")意味着他们相信内联该特定函数会提高性能。这是一个例子:

@pragma("vm:prefer-inline")
void myFooInlineFunction() {
  // Function code
}
Run Code Online (Sandbox Code Playgroud)

这向Dart VM表明,无论在哪里调用它,它都应该考虑内联myFooInlineFunction,以期获得性能提升。考虑到代码的具体特征以及对性能的潜在影响,明智地使用此类提示非常重要。


在提示可以具有参数的情况下,可以包含额外的选项对象以提供更具体的信息。

例如:

@pragma('Tool:pragma-name', [param1, param2, ...])
class Foo { }

@pragma('OtherTool:other-pragma')
void foo() { }
Run Code Online (Sandbox Code Playgroud)

这里,类Foo使用特定于工具的编译指示“pragma-name”进行注释,函数 foo 使用特定于 OtherTool 的编译指示“other-pragma”进行注释。

以上可以在dart.dev 文档中找到。


该@pragma("vm:entry-point")注释对于 AOT(Ahead of Time)编译期间的 Tree-Shaking 至关重要。在AOP(面向方面​​编程)中,非侵入式注入逻辑可能不会被主入口点直接调用。如果没有此注释,编译器可能会丢弃此类未使用的逻辑。通过使用@pragma('vm:entry-point'),我们指示编译器在编译期间保留此代码,以防止意外排除。

  • 这没有回答问题 (9认同)
  • @nt4f04und还没有,但是他给出了一个想法。我对pragma的用途有一个大致的了解,但我仍然不明白它是如何工作的。 (2认同)