🛎️

Dart2.15リリースノート和訳要約

2021/12/09に公開

2021年12月9日に発表されたDart2.15リリースノートの日本語訳の要約記事です。
dart pub commandの変更とUnicodeに関するプログラム言語の脆弱性pub.devの脆弱性に関しては触れていません。

isolatesに2種類の変更

Isolate classは、並列処理関連のライブラリです。
今回のアップデートで並列処理のパフォーマンスが向上し、send methodで送信できるオブジェクトが拡張された。

並行処理に関するドキュメント
https://dart.dev/guides/language/concurrency
並行処理に関するサンプルプログラム
https://github.com/dart-lang/samples/tree/master/isolates

isolate groups の追加

メリット

  • 実行速度上昇
  • 可変オブジェクトへのアクセスを防止する(つまり、不変オブジェクトにするということかな?)
  • 共有ヒープで実装
  • Isolate間でオブジェクトを渡すことが可能(= プロセスを分離可能)

解説

groups内のIsolateは、プログラム実行中の内部データ構造を共有するため、プログラム構造を初期化する必要性がなくなりました。これにより、実行速度が100倍以上早くなり生成されたIsolateのメモリ生成量が10~100倍減少した。
またDart2.15以前は、バッファを呼び出す速度が描画より遅いとUIがフリーズする可能性がありました。そのため、共有ヒープ内でオブジェクトを渡すことにより、プロセスを分離可能にしたことで問題を解決しました。
Flutterを2.8にアップグレードすることにより、自動でパフォーマンスが向上します。

solate message passing mechanismのリファクタリング

メリット

  • 中小規模のメッセージの受け渡しが約8倍高速化
  • send()の対応オブジェクトが拡大
    • Null,bool,int,double,String,List or Map,TransferableTypedData,SendPort,Capability

解説

中小規模のメッセージの受け渡しを約8倍高速化した。送信処理を高速化し、メッセージの受信がほとんど一定時間で行われます。
またIsolateが相互に送信できるオブジェクトを拡大(Null,bool,int,double,String,List or Map,TransferableTypedData,SendPort,Capabilityを追加)した。

関数ポインタの追加

関数ポインタのメリットは直接関数名を書いて呼び出さなければいけなかった所で
間接的に呼び出すことが可能になるという点です。
これによって関数を呼び出す側のコードがシンプルになり可読性が上がります。
引用元 : 関数ポインタの基本

関数ポインタの例
class Greeter {
  final String name;
  Greeter(this.name);
  
  void greet(String who) {
    print('$name says: Hello $who!');
  }
}
void main() {
  final m = Greeter('Michael');
  final g = m.greet; // g holds a function pointer to m.greet.
  g('Leaf'); // Invokes and prints "Michael says: Hello Leaf!"
}

メリット

dart:core libraryの使用時、活用することで効率的にコーディングできる。

例:foreach()でiterableを呼び出す

iterableを呼び出す
final m = Greeter('Michael');
['Lasse', 'Bob', 'Erik'].forEach(m.greet);
// Prints "Michael says: Hello Lasse!", "Michael says: Hello Bob!",
// "Michael says: Hello Erik!"

例: .map()Text Widgetを呼び出す

.mapで呼び出し
class FruitWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
        children: ['Apple', 'Orange'].map(Text.new).toList());
  }
}

非ジェネリックメソッドを作成可能

関数ポインタの実装により、非ジェネリック(型パラメータを宣言していない)メソッドが作成可能になりました。

メリット

配列は、複数の要素を格納するために使用できます。 1つの欠点は、同じデータ型の要素を格納できることです。コレクションと呼ばれる多くの値またはオブジェクトを格納するために使用できるC#のクラスがあります。コレクションは、オブジェクトの保存、更新、削除、検索、並べ替えに役立ちます。コレクションのサイズは動的に増減できます。
一部の非ジェネリックコレクションクラスは、ArrayList、SortedList、Stack、Queue、およびHashTableです。各コレクションクラスはIEnumerableインターフェイスを実装します。これは、foreachループを使用して、コレクション内の項目の要素を反復処理するのに役立ちます。
引用元 : C#の非ジェネリックコレクションとは何ですか?

つまりメソッドを使い回し、無駄なメソッドを減らすことが可能になりました。

例:非ジェネリックメソッド

before
T id<T>(T value) => value;
int Function(int) intId = id; // Pre-2.15 workaround.
after
T id<T>(T value) => value;
var intId = id<int>; // New in 2.15.

例:非ジェネリック関数オブジェクト

before
const fo = id; // Tear off `id`, creating a function object.
const c1 = fo<int>; // error 
after
const fo = id; // Tear off `id`, creating a function object.
const c1 = fo<int>; // OK

型リテラルを更新

before
var z = typeOf<List<int>>(); // Pre-2.15 workaround.
after
var z = List<int>; // New in 2.15.

enumの進化

以前のenumと比較するサンプル
https://github.com/flutter/flutter/pull/94496/files

.nameStringを取得

.nameStringが取得可能

Stringの取得
enum MyEnum {
  one, two, three
}
void main() {
  print(MyEnum.one.name);  // "one"
}

名前でenum内を検索可能

検索
print(MyEnum.values.byName('two') == MyEnum.two);  // "true"

名前と値のペアを取得可能

名前&値を取得
final map = MyEnum.values.asNameMap(); 
print(map['three'] == MyEnum.three);  // Prints "true".

Androidで圧縮ポインタが実装

圧縮ポインタにより、メモリ使用量が大幅に削減される。
Dart2.15では、Androidのみサポートしている。だが、将来的にiOSでも有効にすることを検討している。

解説(和訳要約)

32bitアドレス空間(最大4GBのメモリ)のみをサポートする場合、64bit SDKがポインターを効率よく表現する手法です。ポインタを圧縮すると、メモリが大幅に削減します。GPay Appを使用した内部テストでは、ヒープサイズが約10%減少した。
DartSDKの構成オプションの背後にあり、FlutterSDK version2.8は、Androidのビルドでこの構成を有効にしている。

DartDevToolsがDartSDKに標準実装

Dart DevToolsがDartSDKに標準実装になりました。

DevToolsのドキュメント
https://dart.dev/tools/dart-devtools#using-devtools-with-a-command-line-app

Discussion