[benchmark_harness] Move Measure into its on lib (#2092)
diff --git a/pkgs/benchmark_harness/CHANGELOG.md b/pkgs/benchmark_harness/CHANGELOG.md
index fceecb8..f0e24bf 100644
--- a/pkgs/benchmark_harness/CHANGELOG.md
+++ b/pkgs/benchmark_harness/CHANGELOG.md
@@ -1,3 +1,5 @@
+## 2.3.2-wip
+
## 2.3.1
- Move to `dart-lang/tools` monorepo.
diff --git a/pkgs/benchmark_harness/lib/src/benchmark_base.dart b/pkgs/benchmark_harness/lib/src/benchmark_base.dart
index bc874f5..d119d4d 100644
--- a/pkgs/benchmark_harness/lib/src/benchmark_base.dart
+++ b/pkgs/benchmark_harness/lib/src/benchmark_base.dart
@@ -2,8 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'dart:math' as math;
-
+import 'measurement.dart';
import 'score_emitter.dart';
const int minimumMeasureDurationMillis = 2000;
@@ -61,53 +60,3 @@
emitter.emit(name, measure());
}
}
-
-/// Measures the score for this benchmark by executing it enough times
-/// to reach [minimumMillis].
-Measurement measureForImpl(void Function() f, int minimumMillis) {
- final minimumMicros = minimumMillis * 1000;
- // If running a long measurement permit some amount of measurement jitter
- // to avoid discarding results that are almost good, but not quite there.
- final allowedJitter =
- minimumMillis < 1000 ? 0 : (minimumMicros * 0.1).floor();
- var iter = 2;
- var totalIterations = iter;
- final watch = Stopwatch()..start();
- while (true) {
- watch.reset();
- for (var i = 0; i < iter; i++) {
- f();
- }
- final elapsed = watch.elapsedMicroseconds;
- final measurement = Measurement(elapsed, iter, totalIterations);
- if (measurement.elapsedMicros >= (minimumMicros - allowedJitter)) {
- return measurement;
- }
-
- iter = measurement.estimateIterationsNeededToReach(
- minimumMicros: minimumMicros);
- totalIterations += iter;
- }
-}
-
-class Measurement {
- final int elapsedMicros;
- final int iterations;
- final int totalIterations;
-
- Measurement(this.elapsedMicros, this.iterations, this.totalIterations);
-
- double get score => elapsedMicros / iterations;
-
- int estimateIterationsNeededToReach({required int minimumMicros}) {
- final elapsed = roundDownToMillisecond(elapsedMicros);
- return elapsed == 0
- ? iterations * 1000
- : (iterations * math.max(minimumMicros / elapsed, 1.5)).ceil();
- }
-
- static int roundDownToMillisecond(int micros) => (micros ~/ 1000) * 1000;
-
- @override
- String toString() => '$elapsedMicros in $iterations iterations';
-}
diff --git a/pkgs/benchmark_harness/lib/src/measurement.dart b/pkgs/benchmark_harness/lib/src/measurement.dart
new file mode 100644
index 0000000..11119b9
--- /dev/null
+++ b/pkgs/benchmark_harness/lib/src/measurement.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:math' as math;
+
+/// Measures the score for this benchmark by executing it enough times
+/// to reach [minimumMillis].
+///
+/// [f] will be run a minimum of 2 times.
+Measurement measureForImpl(void Function() f, int minimumMillis) {
+ final minimumMicros = minimumMillis * 1000;
+ // If running a long measurement permit some amount of measurement jitter
+ // to avoid discarding results that are almost good, but not quite there.
+ final allowedJitter =
+ minimumMillis < 1000 ? 0 : (minimumMicros * 0.1).floor();
+ var iter = 2;
+ var totalIterations = iter;
+ final watch = Stopwatch()..start();
+ while (true) {
+ watch.reset();
+ for (var i = 0; i < iter; i++) {
+ f();
+ }
+ final elapsed = watch.elapsedMicroseconds;
+ final measurement = Measurement(elapsed, iter, totalIterations);
+ if (measurement.elapsedMicros >= (minimumMicros - allowedJitter)) {
+ return measurement;
+ }
+
+ iter = measurement.estimateIterationsNeededToReach(
+ minimumMicros: minimumMicros);
+ totalIterations += iter;
+ }
+}
+
+class Measurement {
+ Measurement(this.elapsedMicros, this.iterations, this.totalIterations);
+
+ final int elapsedMicros;
+ final int iterations;
+ final int totalIterations;
+
+ double get score => elapsedMicros / iterations;
+
+ int estimateIterationsNeededToReach({required int minimumMicros}) {
+ final elapsed = _roundDownToMillisecond(elapsedMicros);
+ return elapsed == 0
+ ? iterations * 1000
+ : (iterations * math.max(minimumMicros / elapsed, 1.5)).ceil();
+ }
+
+ @override
+ String toString() => '$elapsedMicros in $iterations iterations';
+}
+
+int _roundDownToMillisecond(int micros) => (micros ~/ 1000) * 1000;
diff --git a/pkgs/benchmark_harness/lib/src/perf_benchmark_base.dart b/pkgs/benchmark_harness/lib/src/perf_benchmark_base.dart
index 1b7fb92..a1c3de9 100644
--- a/pkgs/benchmark_harness/lib/src/perf_benchmark_base.dart
+++ b/pkgs/benchmark_harness/lib/src/perf_benchmark_base.dart
@@ -7,6 +7,7 @@
import 'dart:io';
import 'benchmark_base.dart';
+import 'measurement.dart';
import 'score_emitter.dart';
class PerfBenchmarkBase extends BenchmarkBase {
diff --git a/pkgs/benchmark_harness/pubspec.yaml b/pkgs/benchmark_harness/pubspec.yaml
index d9b82e5..8561c2a 100644
--- a/pkgs/benchmark_harness/pubspec.yaml
+++ b/pkgs/benchmark_harness/pubspec.yaml
@@ -1,5 +1,5 @@
name: benchmark_harness
-version: 2.3.1
+version: 2.3.2-wip
description: The official Dart project benchmark harness.
repository: https://github.com/dart-lang/tools/tree/main/pkgs/benchmark_harness
issue_tracker: https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Abenchmark_harness