From cb72164a72941a711ab2bee473f83ef58a8ea0d2 Mon Sep 17 00:00:00 2001 From: Yegor Date: Thu, 24 Aug 2023 14:28:04 -0700 Subject: [PATCH] [web] benchmark the benchmark harness overhead (#132999) Add benchmarks that measure the overhead of the benchmark harness itself. We want the overhead to be minimal. Also, these numbers are useful to judge the quality of real benchmarks. If a real benchmark's result is too close to the harness overhead, then it's likely not measuring enough of useful work. --- .../lib/src/web/bench_harness.dart | 63 +++++++++++++++++++ .../macrobenchmarks/lib/web_benchmarks.dart | 9 ++- 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 dev/benchmarks/macrobenchmarks/lib/src/web/bench_harness.dart diff --git a/dev/benchmarks/macrobenchmarks/lib/src/web/bench_harness.dart b/dev/benchmarks/macrobenchmarks/lib/src/web/bench_harness.dart new file mode 100644 index 0000000000..8c95cf42cf --- /dev/null +++ b/dev/benchmarks/macrobenchmarks/lib/src/web/bench_harness.dart @@ -0,0 +1,63 @@ +// Copyright 2014 The Flutter Authors. 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:ui' as ui; + +import 'package:flutter/material.dart'; + +import 'recorder.dart'; + +class BenchWidgetRecorder extends WidgetRecorder { + BenchWidgetRecorder() : super(name: benchmarkName); + + static const String benchmarkName = 'bench_widget_recorder'; + + @override + Widget createWidget() { + // This is intentionally using a simple widget. The benchmark is meant to + // measure the overhead of the harness, so this method should induce as + // little work as possible. + return const SizedBox.expand(); + } +} + +class BenchWidgetBuildRecorder extends WidgetBuildRecorder { + BenchWidgetBuildRecorder() : super(name: benchmarkName); + + static const String benchmarkName = 'bench_widget_build_recorder'; + + @override + Widget createWidget() { + // This is intentionally using a simple widget. The benchmark is meant to + // measure the overhead of the harness, so this method should induce as + // little work as possible. + return const SizedBox.expand(); + } +} + +class BenchRawRecorder extends RawRecorder { + BenchRawRecorder() : super(name: benchmarkName); + + static const String benchmarkName = 'bench_raw_recorder'; + + @override + void body(Profile profile) { + profile.record('profile.record', () { + // This is intentionally empty. The benchmark only measures the overhead + // of the harness. + }, reported: true); + } +} + +class BenchSceneBuilderRecorder extends SceneBuilderRecorder { + BenchSceneBuilderRecorder() : super(name: benchmarkName); + + static const String benchmarkName = 'bench_scene_builder_recorder'; + + @override + void onDrawFrame(ui.SceneBuilder sceneBuilder) { + // This is intentionally empty. The benchmark only measures the overhead + // of the harness. + } +} diff --git a/dev/benchmarks/macrobenchmarks/lib/web_benchmarks.dart b/dev/benchmarks/macrobenchmarks/lib/web_benchmarks.dart index e4e18d598b..1beddb1779 100644 --- a/dev/benchmarks/macrobenchmarks/lib/web_benchmarks.dart +++ b/dev/benchmarks/macrobenchmarks/lib/web_benchmarks.dart @@ -17,6 +17,7 @@ import 'src/web/bench_clipped_out_pictures.dart'; import 'src/web/bench_default_target_platform.dart'; import 'src/web/bench_draw_rect.dart'; import 'src/web/bench_dynamic_clip_on_static_picture.dart'; +import 'src/web/bench_harness.dart'; import 'src/web/bench_image_decoding.dart'; import 'src/web/bench_material_3.dart'; import 'src/web/bench_material_3_semantics.dart'; @@ -43,7 +44,13 @@ const bool isSkwasm = bool.fromEnvironment('FLUTTER_WEB_USE_SKWASM'); /// When adding a new benchmark, add it to this map. Make sure that the name /// of your benchmark is unique. final Map benchmarks = { - // Benchmarks that run both in CanvasKit and HTML modes + // Benchmarks the overhead of the benchmark harness itself. + BenchRawRecorder.benchmarkName: () => BenchRawRecorder(), + BenchWidgetRecorder.benchmarkName: () => BenchWidgetRecorder(), + BenchWidgetBuildRecorder.benchmarkName: () => BenchWidgetBuildRecorder(), + BenchSceneBuilderRecorder.benchmarkName: () => BenchSceneBuilderRecorder(), + + // Benchmarks that run in all renderers. BenchDefaultTargetPlatform.benchmarkName: () => BenchDefaultTargetPlatform(), BenchBuildImage.benchmarkName: () => BenchBuildImage(), BenchCardInfiniteScroll.benchmarkName: () => BenchCardInfiniteScroll.forward(),