Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
d95a1a70
Unverified
Commit
d95a1a70
authored
Feb 25, 2020
by
Yegor
Committed by
GitHub
Feb 25, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add WidgetBuildRecorder for benchmarking building widgets (#51088)
parent
889e606c
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
164 additions
and
7 deletions
+164
-7
bench_build_material_checkbox.dart
...benchmarks/lib/src/web/bench_build_material_checkbox.dart
+51
-0
recorder.dart
dev/benchmarks/macrobenchmarks/lib/src/web/recorder.dart
+111
-7
web_benchmarks.dart
dev/benchmarks/macrobenchmarks/lib/web_benchmarks.dart
+2
-0
No files found.
dev/benchmarks/macrobenchmarks/lib/src/web/bench_build_material_checkbox.dart
0 → 100644
View file @
d95a1a70
// 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
'package:flutter/material.dart'
;
import
'recorder.dart'
;
/// Measures how expensive it is to construct material checkboxes.
///
/// Creates a 10x10 grid of tristate checkboxes.
class
BenchBuildMaterialCheckbox
extends
WidgetBuildRecorder
{
BenchBuildMaterialCheckbox
()
:
super
(
name:
benchmarkName
);
static
const
String
benchmarkName
=
'build_material_checkbox'
;
static
bool
_isChecked
;
@override
Widget
createWidget
()
{
return
Column
(
children:
List
<
Widget
>.
generate
(
10
,
(
int
i
)
{
return
_buildRow
();
}),
);
}
Row
_buildRow
()
{
if
(
_isChecked
==
null
)
{
_isChecked
=
true
;
}
else
if
(
_isChecked
)
{
_isChecked
=
false
;
}
else
{
_isChecked
=
null
;
}
return
Row
(
children:
List
<
Widget
>.
generate
(
10
,
(
int
i
)
{
return
Expanded
(
child:
Checkbox
(
value:
_isChecked
,
tristate:
true
,
onChanged:
(
bool
newValue
)
{
// Intentionally empty.
},
),
);
}),
);
}
}
dev/benchmarks/macrobenchmarks/lib/src/web/recorder.dart
View file @
d95a1a70
...
...
@@ -183,7 +183,7 @@ abstract class RawRecorder extends Recorder {
/// }
/// }
/// ```
abstract
class
WidgetRecorder
extends
Recorder
{
abstract
class
WidgetRecorder
extends
Recorder
implements
_RecordingWidgetsBindingListener
{
WidgetRecorder
({
@required
String
name
})
:
super
.
_
(
name
);
/// Creates a widget to be benchmarked.
...
...
@@ -198,10 +198,12 @@ abstract class WidgetRecorder extends Recorder {
Stopwatch
_drawFrameStopwatch
;
@override
void
_frameWillDraw
()
{
_drawFrameStopwatch
=
Stopwatch
()..
start
();
}
@override
void
_frameDidDraw
()
{
_frames
.
add
(
FrameMetrics
.
_
(
drawFrameDuration:
_drawFrameStopwatch
.
elapsed
,
...
...
@@ -226,6 +228,100 @@ abstract class WidgetRecorder extends Recorder {
}
}
/// A recorder for measuring the performance of building a widget from scratch
/// starting from an empty frame.
///
/// The recorder will call [createWidget] and render it, then it will pump
/// another frame that clears the screen. It repeats this process, measuring the
/// performance of frames that render the widget and ignoring the frames that
/// clear the screen.
abstract
class
WidgetBuildRecorder
extends
Recorder
implements
_RecordingWidgetsBindingListener
{
WidgetBuildRecorder
({
@required
String
name
})
:
super
.
_
(
name
);
/// Creates a widget to be benchmarked.
///
/// The widget is not expected to animate as we only care about construction
/// of the widget. If you are interested in benchmarking an animation,
/// consider using [WidgetRecorder].
Widget
createWidget
();
final
Completer
<
Profile
>
_profileCompleter
=
Completer
<
Profile
>();
Stopwatch
_drawFrameStopwatch
;
/// Whether in this frame we should call [createWidget] and render it.
///
/// If false, then this frame will clear the screen.
bool
_showWidget
=
true
;
/// The state that hosts the widget under test.
_WidgetBuildRecorderHostState
_hostState
;
Widget
_getWidgetForFrame
()
{
if
(
_showWidget
)
{
return
createWidget
();
}
else
{
return
null
;
}
}
@override
void
_frameWillDraw
()
{
_drawFrameStopwatch
=
Stopwatch
()..
start
();
}
@override
void
_frameDidDraw
()
{
// Only record frames that show the widget.
if
(
_showWidget
)
{
_frames
.
add
(
FrameMetrics
.
_
(
drawFrameDuration:
_drawFrameStopwatch
.
elapsed
,
sceneBuildDuration:
null
,
windowRenderDuration:
null
,
));
}
if
(
_shouldContinue
())
{
_showWidget
=
!
_showWidget
;
_hostState
.
_setStateTrampoline
();
}
else
{
final
Profile
profile
=
_generateProfile
();
_profileCompleter
.
complete
(
profile
);
}
}
@override
Future
<
Profile
>
run
()
{
final
_RecordingWidgetsBinding
binding
=
_RecordingWidgetsBinding
.
ensureInitialized
();
binding
.
_beginRecording
(
this
,
_WidgetBuildRecorderHost
(
this
));
return
_profileCompleter
.
future
;
}
}
/// Hosts widgets created by [WidgetBuildRecorder].
class
_WidgetBuildRecorderHost
extends
StatefulWidget
{
const
_WidgetBuildRecorderHost
(
this
.
recorder
);
final
WidgetBuildRecorder
recorder
;
@override
State
<
StatefulWidget
>
createState
()
=>
recorder
.
_hostState
=
_WidgetBuildRecorderHostState
();
}
class
_WidgetBuildRecorderHostState
extends
State
<
_WidgetBuildRecorderHost
>
{
// This is just to bypass the @protected on setState.
void
_setStateTrampoline
()
{
setState
(()
{});
}
@override
Widget
build
(
BuildContext
context
)
{
return
SizedBox
.
expand
(
child:
widget
.
recorder
.
_getWidgetForFrame
(),
);
}
}
/// Pumps frames and records frame metrics.
abstract
class
Recorder
{
Recorder
.
_
(
this
.
name
);
...
...
@@ -413,6 +509,14 @@ double _computeStandardDeviationForPopulation(Iterable<double> population) {
return
math
.
sqrt
(
sumOfSquaredDeltas
/
population
.
length
);
}
/// Implemented by recorders that use [_RecordingWidgetsBinding] to receive
/// frame life-cycle calls.
abstract
class
_RecordingWidgetsBindingListener
{
bool
_shouldContinue
();
void
_frameWillDraw
();
void
_frameDidDraw
();
}
/// A variant of [WidgetsBinding] that collaborates with a [Recorder] to decide
/// when to stop pumping frames.
///
...
...
@@ -438,10 +542,10 @@ class _RecordingWidgetsBinding extends BindingBase
return
WidgetsBinding
.
instance
as
_RecordingWidgetsBinding
;
}
WidgetRecorder
_record
er
;
_RecordingWidgetsBindingListener
_listen
er
;
void
_beginRecording
(
WidgetRecord
er
recorder
,
Widget
widget
)
{
_
record
er
=
recorder
;
void
_beginRecording
(
_RecordingWidgetsBindingListen
er
recorder
,
Widget
widget
)
{
_
listen
er
=
recorder
;
runApp
(
widget
);
}
...
...
@@ -451,7 +555,7 @@ class _RecordingWidgetsBinding extends BindingBase
@override
void
handleBeginFrame
(
Duration
rawTimeStamp
)
{
_benchmarkStopped
=
!
_
record
er
.
_shouldContinue
();
_benchmarkStopped
=
!
_
listen
er
.
_shouldContinue
();
super
.
handleBeginFrame
(
rawTimeStamp
);
}
...
...
@@ -464,8 +568,8 @@ class _RecordingWidgetsBinding extends BindingBase
@override
void
handleDrawFrame
()
{
_
record
er
.
_frameWillDraw
();
_
listen
er
.
_frameWillDraw
();
super
.
handleDrawFrame
();
_
record
er
.
_frameDidDraw
();
_
listen
er
.
_frameDidDraw
();
}
}
dev/benchmarks/macrobenchmarks/lib/web_benchmarks.dart
View file @
d95a1a70
...
...
@@ -8,6 +8,7 @@ import 'dart:html' as html;
import
'package:macrobenchmarks/src/web/bench_text_out_of_picture_bounds.dart'
;
import
'src/web/bench_build_material_checkbox.dart'
;
import
'src/web/bench_card_infinite_scroll.dart'
;
import
'src/web/bench_draw_rect.dart'
;
import
'src/web/bench_simple_lazy_text_scroll.dart'
;
...
...
@@ -21,6 +22,7 @@ final Map<String, RecorderFactory> benchmarks = <String, RecorderFactory>{
BenchDrawRect
.
benchmarkName
:
()
=>
BenchDrawRect
(),
BenchTextOutOfPictureBounds
.
benchmarkName
:
()
=>
BenchTextOutOfPictureBounds
(),
BenchSimpleLazyTextScroll
.
benchmarkName
:
()
=>
BenchSimpleLazyTextScroll
(),
BenchBuildMaterialCheckbox
.
benchmarkName
:
()
=>
BenchBuildMaterialCheckbox
(),
};
/// Whether we fell back to manual mode.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment