传统上,要迭代
Map
的键和值,您可以这样写:
map.forEach((key, value) {
});
但是随着 Dart 3.0 中引入patterns,你实际上可以将其写为
for (var MapEntry(:key, :value) in map.entries) {
}
事实上,这样的构造在For 和 for-in 循环部分的模式文档中给出了示例。
我想这是否是一种更好的代码风格是主观的,但在性能/内存方面是否有一种方法比另一种更好?
可以通过基准来评估性能:
import 'package:benchmark_runner/benchmark_runner.dart';
void main(List<String> args) {
final mapSize = 100000;
final list = List<int>.generate(mapSize, (index) => index);
final map = {for (var element in list) element: element.toString()};
final result = <int, String>{};
benchmark('Iterating using forEach: map size $mapSize', () {
map.forEach((key, value) {
result[key] = '$value-new';
});
});
result.clear();
benchmark('Iterating over map keys: map size $mapSize', () {
for (final key in map.keys) {
result[key] = '${map[key]!}-new';
}
});
result.clear();
benchmark('Pattern for loop: map size $mapSize', () {
for (final MapEntry(:key, :value) in map.entries) {
result[key] = '$value-new';
}
});
}
地图尺寸 100 的基准分数:
[244ms:881us] Iterating using forEach: map size 100
mean: 7.24 ± 1.030 us, median: 7.032 ± 0.66 us
▆▉▂▂____________ sample size: 40 (averaged over 131 runs)
[242ms:617us] Iterating over map keys: map size 100
mean: 7.50 ± 0.42 us, median: 7.51 ± 0.49 us
▆▄▉▁___ sample size: 41 (averaged over 124 runs)
[236ms:322us] Pattern for loop: map size 100
mean: 9.12 ± 0.48 us, median: 9.11 ± 0.69 us
▇▉▄▁_ sample size: 30 (averaged over 115 runs)
地图大小 100000 的基准分数:
[811ms:165us] Iterating using forEach: map size 100000
mean: 10.47 ± 1.97 ms, median: 9.60 ± 1.66 ms
▉▁▃________ sample size: 49
[890ms:338us] Iterating over map keys: map size 100000
mean: 12.18 ± 2.013 ms, median: 11.20 ± 2.31 ms
▉▁▅______ sample size: 48
[01s:004ms] Pattern for loop: map size 100000
mean: 14.47 ± 2.63 ms, median: 13.97 ± 2.51 ms
▉▃▇_________ sample size: 47
地图大小 1000000 的基准分数:
[04s:144ms] Iterating using forEach: map size 1000000
mean: 217.80 ± 12.30 ms, median: 214.88 ± 18.029 ms
▉▇▂▄ sample size: 10
[06s:004ms] Iterating over map keys: map size 1000000
mean: 353.59 ± 28.75 ms, median: 358.84 ± 57.83 ms
▇▄▂▉ sample size: 10
[06s:947ms] Pattern for loop: map size 1000000
mean: 413.17 ± 10.85 ms, median: 413.095 ± 16.46 ms
▄▉▄▄ sample size: 10
结论:使用
forEach
迭代映射键时,基准分数显示出稍好的性能。然而,对于中等大小的地图,性能增益太小,无法推荐一种风格而不是另一种风格。