Skip to content

Commit 8e2aa64

Browse files
committed
fix: drop benchmark_harness dep, use a plain Stopwatch benchmark
benchmark_harness needs SDK 3.10; the package supports 3.5. No dep now.
1 parent c574542 commit 8e2aa64

2 files changed

Lines changed: 32 additions & 101 deletions

File tree

benchmark/cobs_benchmark.dart

Lines changed: 32 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,131 +1,63 @@
11
// Copyright (c) 2026 Alexander Salas Bastidas <ajsb85@firechip.dev>
22
// SPDX-License-Identifier: MIT
3+
//
4+
// ignore_for_file: avoid_print
35

46
/// Throughput micro-benchmarks for the COBS / COBS/R codecs.
57
///
68
/// Dev tooling only: this file is excluded from the published package via
7-
/// `.pubignore` and is not part of the public API.
9+
/// `.pubignore`, is not part of the public API, and has no package
10+
/// dependencies (a plain `Stopwatch`, so it runs on every supported SDK).
811
///
912
/// Run with:
1013
///
1114
/// ```sh
1215
/// dart run benchmark/cobs_benchmark.dart
1316
/// ```
1417
///
15-
/// Each benchmark processes a single 1 KiB (1024-byte) payload per `run()`.
16-
/// `exercise()` is overridden to invoke `run()` exactly once, so
17-
/// `BenchmarkBase.measure()` returns microseconds per operation. Throughput is
18-
/// reported as `payloadBytes / time`; because one byte per microsecond equals
19-
/// one decimal megabyte per second, `MB/s == payloadBytes / usPerOp`.
18+
/// Each operation processes a single 1 KiB (1024-byte) payload; throughput is
19+
/// reported as decimal MB/s (`payloadBytes * iterations / seconds / 1e6`).
2020
library;
2121

22-
import 'dart:io';
2322
import 'dart:typed_data';
2423

25-
import 'package:benchmark_harness/benchmark_harness.dart';
2624
import 'package:cobs_codec/cobs_codec.dart';
2725

28-
/// Size of the representative payload, in bytes (1 KiB).
29-
const int payloadBytes = 1024;
30-
31-
/// Builds a deterministic, mostly-non-zero payload with roughly one in eight
32-
/// bytes set to `0x00`, so the COBS zero-delimited block path is exercised.
33-
///
34-
/// Uses a fixed-seed xorshift32 generator so the payload is identical across
35-
/// runs and platforms, making results comparable over time.
36-
Uint8List buildPayload(int length) {
37-
final data = Uint8List(length);
38-
var state = 0x12345678; // fixed seed -> reproducible pattern
26+
/// A deterministic 1 KiB payload with roughly one zero byte in eight, so the
27+
/// COBS block-splitting path is exercised.
28+
Uint8List _makePayload(int length) {
29+
final bytes = Uint8List(length);
30+
var state = 0x12345678;
3931
for (var i = 0; i < length; i++) {
40-
state ^= (state << 13) & 0xFFFFFFFF;
41-
state ^= state >> 17;
42-
state ^= (state << 5) & 0xFFFFFFFF;
43-
final b = state & 0xFF;
44-
// ~1/8 of bytes become zero; the rest keep a guaranteed-non-zero value.
45-
data[i] = (b & 7) == 0 ? 0 : b;
32+
state = (state * 1103515245 + 12345) & 0x7fffffff;
33+
bytes[i] = (state % 8 == 0) ? 0 : (state & 0xff);
4634
}
47-
return data;
35+
return bytes;
4836
}
4937

50-
/// Benchmarks a full COBS encode of the 1 KiB payload.
51-
class CobsEncodeBenchmark extends BenchmarkBase {
52-
CobsEncodeBenchmark(this.payload) : super('cobsEncode');
53-
54-
final Uint8List payload;
55-
56-
@override
57-
void exercise() => run();
58-
59-
@override
60-
void run() {
61-
cobsEncode(payload);
38+
/// Warms up, then times [operation] over many iterations and prints its
39+
/// throughput in decimal MB/s relative to [payloadBytes] bytes per call.
40+
double _benchmark(String name, int payloadBytes, void Function() operation) {
41+
for (var i = 0; i < 20000; i++) {
42+
operation();
6243
}
63-
}
64-
65-
/// Benchmarks a full COBS decode of the encoded 1 KiB payload.
66-
class CobsDecodeBenchmark extends BenchmarkBase {
67-
CobsDecodeBenchmark(this.encoded) : super('cobsDecode');
68-
69-
final Uint8List encoded;
70-
71-
@override
72-
void exercise() => run();
73-
74-
@override
75-
void run() {
76-
cobsDecode(encoded);
77-
}
78-
}
79-
80-
/// Benchmarks a full COBS/R encode of the 1 KiB payload.
81-
class CobsrEncodeBenchmark extends BenchmarkBase {
82-
CobsrEncodeBenchmark(this.payload) : super('cobsrEncode');
83-
84-
final Uint8List payload;
85-
86-
@override
87-
void exercise() => run();
88-
89-
@override
90-
void run() {
91-
cobsrEncode(payload);
44+
const iterations = 500000;
45+
final stopwatch = Stopwatch()..start();
46+
for (var i = 0; i < iterations; i++) {
47+
operation();
9248
}
49+
stopwatch.stop();
50+
final seconds = stopwatch.elapsedMicroseconds / 1e6;
51+
final mbps = payloadBytes * iterations / seconds / 1e6;
52+
print('${name.padRight(12)} ${mbps.toStringAsFixed(1)} MB/s');
53+
return mbps;
9354
}
9455

9556
void main() {
96-
final payload = buildPayload(payloadBytes);
57+
final payload = _makePayload(1024);
9758
final encoded = cobsEncode(payload);
98-
final zeros = payload.where((b) => b == 0).length;
99-
100-
stdout.writeln('cobs_codec throughput benchmark');
101-
stdout.writeln(' Dart: ${Platform.version}');
102-
stdout.writeln(
103-
' OS: ${Platform.operatingSystem} '
104-
'(${Platform.operatingSystemVersion})',
105-
);
106-
stdout.writeln(
107-
' Payload: $payloadBytes bytes '
108-
'($zeros zero / ${payloadBytes - zeros} non-zero), '
109-
'COBS-encoded to ${encoded.length} bytes',
110-
);
111-
stdout.writeln();
11259

113-
final benchmarks = <BenchmarkBase>[
114-
CobsEncodeBenchmark(payload),
115-
CobsDecodeBenchmark(encoded),
116-
CobsrEncodeBenchmark(payload),
117-
];
118-
119-
stdout.writeln(' benchmark us/op MB/s');
120-
stdout.writeln(' ----------- -------- ---------');
121-
for (final benchmark in benchmarks) {
122-
final usPerOp = benchmark.measure(); // microseconds per single run()
123-
// 1 byte/us == 1e6 bytes/s == 1 MB/s (decimal), so MB/s == bytes / us.
124-
final mbPerSecond = payloadBytes / usPerOp;
125-
stdout.writeln(
126-
' ${benchmark.name.padRight(11)} '
127-
'${usPerOp.toStringAsFixed(3).padLeft(8)} '
128-
'${mbPerSecond.toStringAsFixed(1).padLeft(9)}',
129-
);
130-
}
60+
_benchmark('cobsEncode', payload.length, () => cobsEncode(payload));
61+
_benchmark('cobsDecode', payload.length, () => cobsDecode(encoded));
62+
_benchmark('cobsrEncode', payload.length, () => cobsrEncode(payload));
13163
}

pubspec.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,5 @@ environment:
1818
sdk: ^3.5.0
1919

2020
dev_dependencies:
21-
benchmark_harness: ^2.4.0
2221
lints: ">=5.0.0 <7.0.0"
2322
test: ^1.25.0

0 commit comments

Comments
 (0)