简单聊聊 Dart 的 JIT 和 AOT 模式_android

本文主要简单聊聊 Dart 的 JIT 和 AOT 模式

Dart 官方有如下介绍:

Dart Native includes both a Dart VM with JIT (just-in-time) compilation and an AOT (ahead-of-time) compiler for producing machine code

简单聊聊 Dart 的 JIT 和 AOT 模式_面试_02

-w725

Dart Native enables running Dart code compiled to native ARM or X64 machine code for mobile, desktop, and server apps.

简单来说,Dart Native 同时支持 JIT 和 AOT。Dart 这种设计好处如下:

  • Dart VM JIT 便于轻量快速开发,它既支持纯解释执行,也可对代码进行运行时优化
  • Dart AOT 编译器将代码编译成原生的 ARM 或 X64 代码,提升发布的代码运行效率

命令行工具

Dart SDK 分别为 JIT 和 AOT 提供不同的工具。

dart VM tool

dart | Dart

You can use the dart tool (bin/dart) to run Dart command-line apps such as server-side scripts, programs, and servers.

dart 命令支持如下的常用选项:

  • --enable-asserts - 开启断言
  • --version - 查看 Dart VM 版本

另外它还支持 Observatory 选项,用于分析和调试 Dart 程序。常用选项包括:

  • --enable-vm-service - 在本地 8181 端口开启 Observatory 服务
  • --observe - 相当于同时指定 --enable-vm-service--pause-isolates-on-exit

简单聊聊 Dart 的 JIT 和 AOT 模式_Dart_03

-w794

(小技巧:如果你是使用的是 iTerm,按住 Command 键后将光标放在)

关于 Observatory 的更多用法见 Observatory

dart2native

Releases before Dart 2.6 contained a tool named dart2aot that produced AOT snapshots. The dart2native command replaces dart2aot and has a superset of the dart2aot functionality.

Dart 2.6 is now available, with support for compiling to self-contained, native executables.

Dart 语言本身还在快速演化中。所以要注意以下变化:

  • 在 Dart 2.6 以及之前版本,dart2aot 用于生成 AOT 镜像
  • Dart 2.6 之后,dart2native 命令取代了 dart2aot (前者是后者的超集)。

Dart 2.6 近期刚刚发布,这个版本开始才支持将 Dart 代码编译成自包含、独立的原生可执行程序。(当然,这只是形式上的改进,并不是 Dart 中的新技术,因为相关技术很早用于 Flutter 平台了)。

使用 dart2native 命令将对 Dart 程序进行 AOT (ahead-of-time) 编译,生成原生 ARM 或 X64 机器码。

dart2native 命令的产物分成两种。一种是 独立的可执行程序 (缺省是这种),它是原生的机器码,由 Dart 代码及其依赖编译而来,再加上一个很小用于类型检查和垃圾回收的 Dart 运行时。

dart2native 命令用法如下:

dart2native bin/main.dart -o bin/my_app
cp bin/my_app .
./my_app

另一种是 AOT snapshot,它不包含 Dart 运行时,所以需要使用 dartaotruntime 来运行。

dartaotruntime

dartaotruntime 命令用法如下:

dart2native bin/main.dart -k aot
dartaotruntime bin/main.aot

Flutter 采用 AOT snapshot 这种形式。讲 Flutter 架构时会看到这张图,

简单聊聊 Dart 的 JIT 和 AOT 模式_android_04

img

图中 Flutter Engine 层中的 Dart 即 Dart 运行时,也正是这里提到的 dartaotruntime

不过 Flutter 自带的 Dart SDK 中似乎找不到 dart2aotdart2native 命令,以下两个 issue 提到了这个问题。

Announcing Dart 2.6 with dart2native: Compile Dart to self-contained, native executables 对 Flutter 中不包含 dart2aotdart2native 有如下解释:

If you’re getting the Dart SDK via Flutter, note that current Flutter builds have incomplete dart2native support. Until Dart 2.6 reaches Flutter stable, we recommend you install the Dart 2.6 SDK from dart.dev/get-dart.

可以从 Dart 官网 下载安装 Dart SDK,它包含 dart2native 命令。

简单聊聊 Dart 的 JIT 和 AOT 模式_android_05

Dart SDK 中的 dart2native 命令

性能测试

写一个简单的 Dart 程序分别测试下 JIT 和 AOT 模式的性能。

// demo.dart
main(List<String> args) {
  double area;
  for (int i = 0; i < 50000000; i++) {
    area = i * 3.14 * 3.14;
  }
}

简单聊聊 Dart 的 JIT 和 AOT 模式_Dart_06

-w779

从测试数据可以看到,AOT 下的执行效率确实比 JIT 高多了。

这篇文章 中 “Dart is as slow as Python” 这一节提到了 Dart 的性能问题,这里可以找到很多参考数据

参考

最后
这里也为想要学习Flutter的朋友们准备了两份学习资料《Flutter Dart语言编程入门到精通》《Flutter实战》,从编程语言到项目实战,一条龙服务!!

《Flutter Dart 语言编程入门到精通》

  • 第一章 Dart语言基础
  • 第二章 Dart 异步编程
  • 简单聊聊 Dart 的 JIT 和 AOT 模式_android_07

  • 第三章 异步之 Stream 详解
  • 第四章 Dart标准输入输出流
  • 简单聊聊 Dart 的 JIT 和 AOT 模式_笔记_08

  • 第五章 Dart 网络编程
  • 第六章 Flutter 爬虫与服务端
  • 简单聊聊 Dart 的 JIT 和 AOT 模式_面试_09

  • 第七章 Dart 的服务端开发
  • 第八章 Dart 调用C语言混合编程
  • 第九章 LuaDardo中Dart与Lua的相互调用
  • 简单聊聊 Dart 的 JIT 和 AOT 模式_面试_10

《Flutter实战:第二版》

  • 第一章:起步
  • 第二章:第一个Flutter应用
  • 第三章:基础组件
  • 第四章:布局类组件
  • 第五章:容器类组件

简单聊聊 Dart 的 JIT 和 AOT 模式_职场和发展_11

  • 第六章:可滚动组件
  • 第七章:功能型组件
  • 第八章:事件处理与通知
  • 第九章:动画
  • 第十章:自定义组件
  • 简单聊聊 Dart 的 JIT 和 AOT 模式_android_12

  • 第十一章:文件操作与网络请求
  • 第十二章:Flutter扩展
  • 第十三章:国际化
  • 第十四章:Flutter核心原理
  • 第十五章:一个完整的Flutter应用
  • 简单聊聊 Dart 的 JIT 和 AOT 模式_职场和发展_13