Flutter:动画严重降低磁盘写入速度

Flutter: Animations badly slow down disk write speed

不确定这是一个 bug 还是这些东西是如何工作的,或者我做错了什么。

我正在制作一个应用程序,它可以解析一些数据的文本文件,然后将其存储在 sqlite 数据库中。在某些时候,我决定添加基本的微调器来指示正在进行的解析,因为平均文件通常需要几秒钟。

所以我添加了一个三元运算符,如果 isBusy 变量设置为 true,它会呈现 CircularProgressIndicator()。而我的解析时间突然增加到原来的 10 倍左右。那是 Linux。在 Android 上,它也会减慢进程,但只会额外增加 ~70%。我检查了几件事,看起来任何动画都会导致这个问题,例如AnimatedContainer.

重现步骤:

  1. 运行下面的代码,注意对话框中的完成时间。
  2. 取消注释 CircularProgressIndicator()AnimatedContainer 块并再次 运行 代码。请注意现在需要多长时间。
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';

const Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(
        scaffoldBackgroundColor: darkBlue,
      ),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

class MyWidget extends StatefulWidget {
  @override
  State<MyWidget> createState() => _MyWidget();
}

class _MyWidget extends State<MyWidget> {
  var _width = 50.0;
  var _height = 50.0;

  void startHeavyOperation() async {
    final directory = await getApplicationDocumentsDirectory();
    var myFile = File('${directory.path}/test.txt');

    const max = 10000;
    var x = 0;

    setState(() {
      _width = 300;
      _height = 300;
    });

    final startTime = DateTime.now();

    while (x < max) {
      await myFile.writeAsString('$x\n', mode: FileMode.append);
      x += 1;
    }

    final endTime = DateTime.now();
    final durationInMilliseconds = endTime.difference(startTime).inMilliseconds;

    showDialog(
      context: context,
      builder: (ctx) => AlertDialog(
        title: Text('It took $durationInMilliseconds ms'),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          ElevatedButton(
            onPressed: () => startHeavyOperation(),
            child: const Text('startHeavyOperation'),
          ),
          // AnimatedContainer(
          //   duration: Duration(seconds: 10),
          //   child: Text('123'),
          //   color: Colors.red,
          //   width: _width,
          //   height: _height,
          // ),

          // CircularProgressIndicator(),
        ],
      ),
    );
  }
}

我的问题是:有没有办法使用动画 w/o 减慢磁盘写入速度?

是的 - 我怀疑这确实是动画。尝试将繁重的操作隔离 - 我怀疑这会加快速度(在设备上)。 Here's an example.

即使没有动画,while 语句也非常昂贵。放入单独的隔离物将为您节省一些时间。这是对您的代码示例的快速修改。 compute给你一个未来


void startHeavyOperation(String path) async {

  var myFile = File('$path/test.txt');

  const max = 10000;
  var x = 0;

  final startTime = DateTime.now();

  while (x < max) {
    await myFile.writeAsString('$x\n', mode: FileMode.append);
    x += 1;
  }

  final endTime = DateTime.now();
  final durationInMilliseconds = endTime.difference(startTime).inMilliseconds;

  print('It took $durationInMilliseconds ms');
}

class MyWidget extends StatefulWidget {
  @override
  State<MyWidget> createState() => _MyWidget();
}

class _MyWidget extends State<MyWidget> {
  var _width = 50.0;
  var _height = 50.0;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          ElevatedButton(
            onPressed: () async {
              final directory = await getApplicationDocumentsDirectory();
              compute(startHeavyOperation, directory.path);
            },
            child: const Text('startHeavyOperation'),
          ),
          // AnimatedContainer(
          //   duration: Duration(seconds: 10),
          //   child: Text('123'),
          //   color: Colors.red,
          //   width: _width,
          //   height: _height,
          // ),
          //
          CircularProgressIndicator(),
        ],
      ),
    );
  }
}