Flutter:动画严重降低磁盘写入速度
Flutter: Animations badly slow down disk write speed
不确定这是一个 bug 还是这些东西是如何工作的,或者我做错了什么。
我正在制作一个应用程序,它可以解析一些数据的文本文件,然后将其存储在 sqlite 数据库中。在某些时候,我决定添加基本的微调器来指示正在进行的解析,因为平均文件通常需要几秒钟。
所以我添加了一个三元运算符,如果 isBusy
变量设置为 true,它会呈现 CircularProgressIndicator()
。而我的解析时间突然增加到原来的 10 倍左右。那是 Linux。在 Android 上,它也会减慢进程,但只会额外增加 ~70%。我检查了几件事,看起来任何动画都会导致这个问题,例如AnimatedContainer
.
重现步骤:
- 运行下面的代码,注意对话框中的完成时间。
- 取消注释
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(),
],
),
);
}
}
不确定这是一个 bug 还是这些东西是如何工作的,或者我做错了什么。
我正在制作一个应用程序,它可以解析一些数据的文本文件,然后将其存储在 sqlite 数据库中。在某些时候,我决定添加基本的微调器来指示正在进行的解析,因为平均文件通常需要几秒钟。
所以我添加了一个三元运算符,如果 isBusy
变量设置为 true,它会呈现 CircularProgressIndicator()
。而我的解析时间突然增加到原来的 10 倍左右。那是 Linux。在 Android 上,它也会减慢进程,但只会额外增加 ~70%。我检查了几件事,看起来任何动画都会导致这个问题,例如AnimatedContainer
.
重现步骤:
- 运行下面的代码,注意对话框中的完成时间。
- 取消注释
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(),
],
),
);
}
}