diff --git a/benchmarks/README.md b/benchmarks/README.md new file mode 100644 index 00000000..e07f36eb --- /dev/null +++ b/benchmarks/README.md @@ -0,0 +1,62 @@ +# Equatable Benchmarks + +Benchmarks used to measure the performance of equality comparisons using `package:equatable`. + +## Quick Start + +1. Install dependencies + `dart pub get` +1. Run the benchmarks + `dart run main.dart` + +## Results + +``` +EmptyEquatable + total runs: 2 076 295 + total time: 2.0000 s + average run: 0 μs + runs/second: Infinity + units: 100 + units/second: Infinity + time per unit: 0.0000 μs + +PrimitiveEquatable + total runs: 810 588 + total time: 2.0000 s + average run: 2 μs + runs/second: 500 000 + units: 100 + units/second: 50 000 000 + time per unit: 0.0200 μs + +CollectionEquatable (small) + total runs: 443 978 + total time: 2.0000 s + average run: 4 μs + runs/second: 250 000 + units: 100 + units/second: 25 000 000 + time per unit: 0.0400 μs + +CollectionEquatable (medium) + total runs: 442 368 + total time: 2.0000 s + average run: 4 μs + runs/second: 250 000 + units: 100 + units/second: 25 000 000 + time per unit: 0.0400 μs + +CollectionEquatable (large) + total runs: 450 915 + total time: 2.0000 s + average run: 4 μs + runs/second: 250 000 + units: 100 + units/second: 25 000 000 + time per unit: 0.0400 μs +``` + +*Run on a MacBook Pro (M1 Pro, 16GB RAM)* +*Last Updated: May 26, 2024 using `725b76c9ef072695f3ae4f036c4fa5e015528f13`* \ No newline at end of file diff --git a/benchmarks/main.dart b/benchmarks/main.dart new file mode 100644 index 00000000..5a226d26 --- /dev/null +++ b/benchmarks/main.dart @@ -0,0 +1,97 @@ +import 'package:benchmarking/benchmarking.dart'; +import 'package:equatable/equatable.dart'; + +class EmptyEquatable extends Equatable { + @override + List get props => []; +} + +class PrimitiveEquatable extends Equatable { + const PrimitiveEquatable({ + required this.integer, + required this.string, + required this.boolean, + }); + + final int integer; + final String string; + final bool boolean; + + @override + List get props => [integer, string, boolean]; +} + +class CollectionEquatable extends Equatable { + const CollectionEquatable({ + required this.list, + required this.map, + required this.set, + }); + + final List list; + final Map map; + final Set set; + + @override + List get props => [list, map, set]; +} + +void main() { + _runBenchmark('EmptyEquatable', (_) => EmptyEquatable()); + + _runBenchmark( + 'PrimitiveEquatable', + (index) => PrimitiveEquatable( + integer: index, + string: '$index', + boolean: index.isEven, + ), + ); + + _runBenchmark( + 'CollectionEquatable (small)', + (index) => CollectionEquatable( + list: List.generate(1, (i) => index + i), + map: Map.fromEntries( + List.generate(1, (i) => MapEntry('${index + i}', index + i)), + ), + set: Set.from(List.generate(1, (i) => index + i)), + ), + ); + + _runBenchmark( + 'CollectionEquatable (medium)', + (index) => CollectionEquatable( + list: List.generate(10, (i) => index + i), + map: Map.fromEntries( + List.generate(10, (i) => MapEntry('${index + i}', index + i)), + ), + set: Set.from(List.generate(10, (i) => index + i)), + ), + ); + + _runBenchmark( + 'CollectionEquatable (large)', + (index) => CollectionEquatable( + list: List.generate(100, (i) => index + i), + map: Map.fromEntries( + List.generate(100, (i) => MapEntry('${index + i}', index + i)), + ), + set: Set.from(List.generate(100, (i) => index + i)), + ), + ); +} + +void _runBenchmark(String name, Object Function(int index) create) { + const poolSize = 100; + final pool = List.generate(poolSize, create); + final poolA = [...pool]..shuffle(); + final poolB = [...pool]..shuffle(); + bool? result; // so that the loop isn't optimized out + syncBenchmark(name, () { + for (var i = 0; i < poolSize; i++) { + result = poolA[i] == poolB[i]; + } + }).report(units: poolSize); + assert(result != null, 'result should be defined.'); +} diff --git a/benchmarks/pubspec.yaml b/benchmarks/pubspec.yaml new file mode 100644 index 00000000..380774da --- /dev/null +++ b/benchmarks/pubspec.yaml @@ -0,0 +1,12 @@ +name: equatable_benchmarks +publish_to: none + +environment: + sdk: ">=2.12.0 <3.0.0" + +dependencies: + equatable: ^2.0.0 + +dev_dependencies: + benchmarking: ^0.6.1 + test: ^1.16.0 diff --git a/benchmarks/pubspec_overrides.yaml b/benchmarks/pubspec_overrides.yaml new file mode 100644 index 00000000..1c5c27ac --- /dev/null +++ b/benchmarks/pubspec_overrides.yaml @@ -0,0 +1,3 @@ +dependency_overrides: + equatable: + path: ../