Flutter高效对象比较插件fast_equatable的使用
Flutter高效对象比较插件fast_equatable的使用
概述
这是一个简单的Dart包,提供了快速且安全的对象相等性比较功能,作为mixin
实现。这为现有的代码提供了良好的兼容性。
它还提供了可选的哈希缓存功能,以显著提高例如Map
和Set
的速度。
默认情况下,使用的是广泛传播的詹金斯散列函数,但你也可以实现并提供自己的哈希引擎,以满足你的需求。
任何类型的对象都可以放入hashParameters
。默认支持简单类型和标准集合,如List
、Iterable
、Map
和Set
。当你使用自定义类时,请确保也使用FastEquatable
mixin,或者至少重写hashCode
和operator ==
方法。
示例
class FastEquatableCached with FastEquatable {
final String value1;
final List<String>? value2;
FastEquatableCached(this.value1, this.value2);
[@override](/user/override)
// 这是一个不可变对象,所以我们想要缓存哈希值
bool get cacheHash => true;
[@override](/user/override)
List<Object?> get hashParameters => [value1, value2];
}
性能测试
在example
文件夹中,你可以找到一个性能测试代码,展示了由此带来的速度提升。
equatable for 1000000 elements(RunTime): 8583044.5 us.
fast_equatable (uncached) for 1000000 elements(RunTime): 8493327.5 us.
fast_equatable (cached) for 1000000 elements(RunTime): 3329455.5 us.
完整示例代码
import 'dart:math';
import 'package:benchmark_harness/benchmark_harness.dart';
import 'package:equatable/equatable.dart';
import 'package:fast_equatable/fast_equatable.dart';
// 使用FastEquatable mixin的带缓存的类
class FastEquatableCached with FastEquatable {
final String value1;
final List<String>? value2;
FastEquatableCached(this.value1, this.value2);
[@override](/user/override)
// 这是一个不可变对象,所以我们想要缓存哈希值
bool get cacheHash => true;
[@override](/user/override)
List<Object?> get hashParameters => [value1, value2];
}
// 使用FastEquatable mixin的不带缓存的类
class FastEquatableUncached with FastEquatable {
final String value1;
final List<String>? value2;
FastEquatableUncached(this.value1, this.value2);
[@override](/user/override)
// 不需要缓存哈希值
bool get cacheHash => false;
[@override](/user/override)
List<Object?> get hashParameters => [value1, value2];
}
// 使用Equatable库的类
class TestClassEquatable extends Equatable {
final String value1;
final List<String>? value2;
const TestClassEquatable(this.value1, this.value2);
[@override](/user/override)
List<Object?> get props => [value1, value2];
}
// 基准测试基类
abstract class BenchmarkBase extends BenchmarkBase {
final List<String> _randsValA;
final List<String> _randsValB;
late final List<TestClassEquatable> objects;
BenchmarkBase(this._randsValA, this._randsValB)
: assert(_randsValA.length == _randsValB.length),
super('基准测试');
[@override](/user/override)
void setup() {
objects = List.generate(_randsValA.length,
(i) => TestClassEquatable(_randsValA[i], [_randsValB[i]]));
}
[@override](/user/override)
void run() {
final set = <TestClassEquatable>{};
for (final obj in objects) {
set.add(obj);
}
}
}
// 使用Equatable库的基准测试类
class EquatableBenchmark extends BenchmarkBase {
EquatableBenchmark(super._randsValA, super._randsValB)
: super('equatable for ${_randsValA.length} elements');
[@override](/user/override)
void run() {
final set = <TestClassEquatable>{};
for (final obj in objects) {
set.add(obj);
}
}
}
// 使用FastEquatable不带缓存的基准测试类
class FastEquatableUncachedBenchmark extends BenchmarkBase {
FastEquatableUncachedBenchmark(super._randsValA, super._randsValB)
: super('fast_equatable (uncached) for ${_randsValA.length} elements');
[@override](/user/override)
void run() {
final set = <FastEquatableUncached>{};
for (final obj in objects) {
set.add(obj);
}
}
}
// 使用FastEquatable带缓存的基准测试类
class FastEquatableCachedBenchmark extends BenchmarkBase {
FastEquatableCachedBenchmark(super._randsValA, super._randsValB)
: super('fast_equatable (cached) for ${_randsValA.length} elements');
[@override](/user/override)
void run() {
final set = <FastEquatableCached>{};
for (final obj in objects) {
set.add(obj);
}
}
}
void main(List<String> args) {
const int nAcc = 1000000;
final rand = Random();
final randsVal1 = List.generate(nAcc, (_) => rand.nextInt(nAcc).toString());
final randsVal2 = List.generate(nAcc, (_) => rand.nextInt(nAcc).toString());
EquatableBenchmark(randsVal1, randsVal2).report();
FastEquatableUncachedBenchmark(randsVal1, randsVal2).report();
FastEquatableCachedBenchmark(randsVal1, randsVal2).report();
}
更多关于Flutter高效对象比较插件fast_equatable的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter高效对象比较插件fast_equatable的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter项目中使用fast_equatable
插件进行高效对象比较的示例代码。
1. 添加依赖
首先,你需要在pubspec.yaml
文件中添加fast_equatable
依赖:
dependencies:
flutter:
sdk: flutter
fast_equatable: ^3.0.0 # 请根据需要检查最新版本号
然后运行flutter pub get
来安装依赖。
2. 创建一个数据模型
接下来,创建一个数据模型,并让它继承Equatable
类。Equatable
类来自fast_equatable
包,它允许你通过指定哪些字段用于比较对象是否相等。
import 'package:fast_equatable/fast_equatable.dart';
class User extends Equatable {
final String id;
final String name;
final int age;
User({required this.id, required this.name, required this.age});
@override
List<Object?> get props => [id, name, age];
}
在上面的代码中,User
类有三个属性:id
、name
和age
。props
getter方法返回一个包含用于比较的字段的列表。
3. 使用对象比较
现在你可以创建User
对象并使用==
运算符或===
运算符(对于引用比较)来比较它们。由于我们使用了Equatable
,==
运算符会比较props
中指定的字段。
void main() {
User user1 = User(id: '1', name: 'Alice', age: 30);
User user2 = User(id: '1', name: 'Alice', age: 30);
User user3 = User(id: '2', name: 'Bob', age: 25);
print(user1 == user2); // 输出: true
print(user1 == user3); // 输出: false
}
在上面的代码中,user1
和user2
具有相同的属性值,因此它们被认为是相等的。而user3
的属性值与user1
不同,所以它们不相等。
4. 在Flutter Widget中使用
你也可以在Flutter Widget中使用这些对象,并进行比较。例如,在ListView.builder
中渲染用户列表,并根据某些条件更新UI。
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('fast_equatable Example')),
body: UserList(),
),
);
}
}
class UserList extends StatefulWidget {
@override
_UserListState createState() => _UserListState();
}
class _UserListState extends State<UserList> {
List<User> users = [
User(id: '1', name: 'Alice', age: 30),
User(id: '2', name: 'Bob', age: 25),
];
void _addUser() {
setState(() {
users.add(User(id: '3', name: 'Charlie', age: 35));
});
}
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Expanded(
child: ListView.builder(
itemCount: users.length,
itemBuilder: (context, index) {
return ListTile(
title: Text('${users[index].name} (${users[index].age})'),
);
},
),
),
ElevatedButton(
onPressed: _addUser,
child: Text('Add User'),
),
],
);
}
}
在这个例子中,我们创建了一个简单的Flutter应用,它显示了一个用户列表,并允许你通过点击按钮添加新用户。由于我们使用了fast_equatable
,所以Flutter框架可以高效地比较User
对象,并在必要时更新UI。
希望这个示例代码能帮助你理解如何在Flutter项目中使用fast_equatable
进行高效对象比较。