つくるの大好き。

つくるのが大好きな人の記録。

Flutterはじめました / DartのTimerの精度を調べてみた

新年あけましておめでとうございます!

Flutter (Dart言語) はじめました

最近はFlutter (Dart言語) を触ることが増えています。
入門して1ヶ月少々の超ビギナーなので、調べてわかったことをメモして行こうかなと思っています。
もっと良い方法をご存知でしたらぜひ教えてください。

Timerの精度を調べるコード

秒間60回程度の頻度でタスクを実行する仕組みが作りたいなと思いました。 こういう場合Dartはシングルスレッドで動作するので、定期的なタスクはTimerで作れば良さそうです。

テストコード
https://github.com/satoshi-maemoto/studying_flutter/blob/main/integration_test/timer_test.dart

tester.printToConsole("=== START ${tester.testDescription} ===");

var desiredFps = 60.0;
var testSeconds = 10;

var duration = Duration(microseconds: (1000000.0 / desiredFps).truncate());
var called = 0;
var start = DateTime.now();
tester.printToConsole(
    "START: ${start.toString()} desiredFps:$desiredFps duration:${duration.toString()}");
var clock = Timer.periodic(duration, (t) {
    ++called;
    //tester.printToConsole(DateTime.now().toString());
});

await Future.delayed(Duration(seconds: testSeconds));

clock.cancel();
var end = DateTime.now();
var actualFps =
    called.toDouble() / (end.difference(start).inMicroseconds / 1000000.0);
tester.printToConsole(
    "END:   ${end.toString()} called:$called difference:${end.difference(start)} actualFps:$actualFps");

1秒間に60回の呼び出しを期待しつつ、10秒後に平均のレートを出力するコードです。

テスト結果

  • iPhone 14 Pro
    START: 2023-02-05 17:53:32.903171 desiredFps:60.0 duration:0:00:00.016666
    END: 2023-02-05 17:53:42.907459 called:625 difference:0:00:10.004288 actualFps:62.47321148691441

  • Xperia1 II
    START: 2023-02-05 17:48:27.789945 desiredFps:60.0 duration:0:00:00.016666
    END: 2023-02-05 17:48:37.796106 called:625 difference:0:00:10.006161 actualFps:62.46151745909345

60回を期待しているところ62.5回の呼び出しがされる模様。
遅いよりは良いけどあんまり正確じゃないなぁ〜。
まあシングルスレッドなので他のところで処理を専有されるとグダグタになることは予想されるな。

まとめ?

というわけでDartのTimerは結構ルーズである模様。
もっと高精度なバックグラウンド処理ができる方法を知っていたらぜひ教えてください。