2025-08-06 22:19:13 +03:00
|
|
|
import 'dart:io';
|
|
|
|
|
import 'dart:math';
|
|
|
|
|
import 'package:benchmark_cherrypick/benchmarks/universal_chain_benchmark.dart';
|
|
|
|
|
import 'package:benchmark_cherrypick/benchmarks/universal_chain_async_benchmark.dart';
|
|
|
|
|
|
2025-08-06 23:15:28 +03:00
|
|
|
/// Holds the results for a single benchmark execution.
|
2025-08-06 22:19:13 +03:00
|
|
|
class BenchmarkResult {
|
2025-08-06 23:15:28 +03:00
|
|
|
/// List of timings for each run (in microseconds).
|
2025-08-06 22:19:13 +03:00
|
|
|
final List<num> timings;
|
2025-08-06 23:15:28 +03:00
|
|
|
/// Difference in memory (RSS, in KB) after running.
|
2025-08-06 22:19:13 +03:00
|
|
|
final int memoryDiffKb;
|
2025-08-06 23:15:28 +03:00
|
|
|
/// Difference between peak RSS and initial RSS (in KB).
|
2025-08-06 22:19:13 +03:00
|
|
|
final int deltaPeakKb;
|
2025-08-06 23:15:28 +03:00
|
|
|
/// Peak RSS memory observed (in KB).
|
2025-08-06 22:19:13 +03:00
|
|
|
final int peakRssKb;
|
|
|
|
|
BenchmarkResult({
|
|
|
|
|
required this.timings,
|
|
|
|
|
required this.memoryDiffKb,
|
|
|
|
|
required this.deltaPeakKb,
|
|
|
|
|
required this.peakRssKb,
|
|
|
|
|
});
|
2025-08-06 23:15:28 +03:00
|
|
|
/// Computes a BenchmarkResult instance from run timings and memory data.
|
2025-08-06 22:19:13 +03:00
|
|
|
factory BenchmarkResult.collect({
|
|
|
|
|
required List<num> timings,
|
|
|
|
|
required List<int> rssValues,
|
|
|
|
|
required int memBefore,
|
|
|
|
|
}) {
|
|
|
|
|
final memAfter = ProcessInfo.currentRss;
|
|
|
|
|
final memDiffKB = ((memAfter - memBefore) / 1024).round();
|
|
|
|
|
final peakRss = [...rssValues, memBefore].reduce(max);
|
|
|
|
|
final deltaPeakKb = ((peakRss - memBefore) / 1024).round();
|
|
|
|
|
return BenchmarkResult(
|
|
|
|
|
timings: timings,
|
|
|
|
|
memoryDiffKb: memDiffKB,
|
|
|
|
|
deltaPeakKb: deltaPeakKb,
|
|
|
|
|
peakRssKb: (peakRss / 1024).round(),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-06 23:15:28 +03:00
|
|
|
/// Static methods to execute and time benchmarks for DI containers.
|
2025-08-06 22:19:13 +03:00
|
|
|
class BenchmarkRunner {
|
2025-08-06 23:15:28 +03:00
|
|
|
/// Runs a synchronous benchmark ([UniversalChainBenchmark]) for a given number of [warmups] and [repeats].
|
|
|
|
|
/// Collects execution time and observed memory.
|
2025-08-06 22:19:13 +03:00
|
|
|
static Future<BenchmarkResult> runSync({
|
|
|
|
|
required UniversalChainBenchmark benchmark,
|
|
|
|
|
required int warmups,
|
|
|
|
|
required int repeats,
|
|
|
|
|
}) async {
|
|
|
|
|
final timings = <num>[];
|
|
|
|
|
final rssValues = <int>[];
|
|
|
|
|
for (int i = 0; i < warmups; i++) {
|
|
|
|
|
benchmark.setup();
|
|
|
|
|
benchmark.run();
|
|
|
|
|
benchmark.teardown();
|
|
|
|
|
}
|
|
|
|
|
final memBefore = ProcessInfo.currentRss;
|
|
|
|
|
for (int i = 0; i < repeats; i++) {
|
|
|
|
|
benchmark.setup();
|
|
|
|
|
final sw = Stopwatch()..start();
|
|
|
|
|
benchmark.run();
|
|
|
|
|
sw.stop();
|
|
|
|
|
timings.add(sw.elapsedMicroseconds);
|
|
|
|
|
rssValues.add(ProcessInfo.currentRss);
|
|
|
|
|
benchmark.teardown();
|
|
|
|
|
}
|
|
|
|
|
return BenchmarkResult.collect(timings: timings, rssValues: rssValues, memBefore: memBefore);
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-06 23:15:28 +03:00
|
|
|
/// Runs an asynchronous benchmark ([UniversalChainAsyncBenchmark]) for a given number of [warmups] and [repeats].
|
|
|
|
|
/// Collects execution time and observed memory.
|
2025-08-06 22:19:13 +03:00
|
|
|
static Future<BenchmarkResult> runAsync({
|
|
|
|
|
required UniversalChainAsyncBenchmark benchmark,
|
|
|
|
|
required int warmups,
|
|
|
|
|
required int repeats,
|
|
|
|
|
}) async {
|
|
|
|
|
final timings = <num>[];
|
|
|
|
|
final rssValues = <int>[];
|
|
|
|
|
for (int i = 0; i < warmups; i++) {
|
|
|
|
|
await benchmark.setup();
|
|
|
|
|
await benchmark.run();
|
|
|
|
|
await benchmark.teardown();
|
|
|
|
|
}
|
|
|
|
|
final memBefore = ProcessInfo.currentRss;
|
|
|
|
|
for (int i = 0; i < repeats; i++) {
|
|
|
|
|
await benchmark.setup();
|
|
|
|
|
final sw = Stopwatch()..start();
|
|
|
|
|
await benchmark.run();
|
|
|
|
|
sw.stop();
|
|
|
|
|
timings.add(sw.elapsedMicroseconds);
|
|
|
|
|
rssValues.add(ProcessInfo.currentRss);
|
|
|
|
|
await benchmark.teardown();
|
|
|
|
|
}
|
|
|
|
|
return BenchmarkResult.collect(timings: timings, rssValues: rssValues, memBefore: memBefore);
|
|
|
|
|
}
|
|
|
|
|
}
|