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
0d077880
Unverified
Commit
0d077880
authored
Apr 01, 2020
by
Yegor
Committed by
GitHub
Apr 01, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add benchmark reproducing large static scrolling content (#53686)
parent
bb5c3400
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
173 additions
and
44 deletions
+173
-44
bench_dynamic_clip_on_static_picture.dart
...rks/lib/src/web/bench_dynamic_clip_on_static_picture.dart
+115
-0
bench_text_out_of_picture_bounds.dart
...chmarks/lib/src/web/bench_text_out_of_picture_bounds.dart
+6
-38
recorder.dart
dev/benchmarks/macrobenchmarks/lib/src/web/recorder.dart
+5
-5
test_data.dart
dev/benchmarks/macrobenchmarks/lib/src/web/test_data.dart
+45
-1
web_benchmarks.dart
dev/benchmarks/macrobenchmarks/lib/web_benchmarks.dart
+2
-0
No files found.
dev/benchmarks/macrobenchmarks/lib/src/web/bench_dynamic_clip_on_static_picture.dart
0 → 100644
View file @
0d077880
// 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'
;
import
'recorder.dart'
;
import
'test_data.dart'
;
/// The height of each row.
const
double
kRowHeight
=
20.0
;
/// Number of rows.
const
int
kRows
=
100
;
/// Number of columns.
const
int
kColumns
=
10
;
/// The amount the picture is scrolled on every iteration of the benchmark.
const
double
kScrollDelta
=
2.0
;
/// Draws one complex picture, then moves a clip around it simulating scrolling
/// large static content.
///
/// This benchmark measures how efficient we are at taking advantage of the
/// static picture when all that changes is the clip.
///
/// See also:
///
/// * `bench_text_out_of_picture_bounds.dart`, which measures a volatile
/// picture with a static clip.
/// * https://github.com/flutter/flutter/issues/42987, which this benchmark is
/// based on.
class
BenchDynamicClipOnStaticPicture
extends
SceneBuilderRecorder
{
BenchDynamicClipOnStaticPicture
()
:
super
(
name:
benchmarkName
)
{
// If the scrollable extent is too small, the benchmark may end up
// scrolling the picture out of the clip area entirely, resulting in
// bogus metric vaules.
const
double
maxScrollExtent
=
kMaxSampleCount
*
kScrollDelta
;
const
double
pictureHeight
=
kRows
*
kRowHeight
;
if
(
maxScrollExtent
>
pictureHeight
)
{
throw
Exception
(
'Bad combination of constant values kRowHeight, kRows, and '
'kScrollData. With these numbers there is risk that the picture '
'will scroll out of the clip entirely. To fix the issue reduce '
'kScrollDelta, or increase either kRows or kRowHeight.'
);
}
// Create one static picture, then never change it again.
const
Color
black
=
Color
.
fromARGB
(
255
,
0
,
0
,
0
);
final
PictureRecorder
pictureRecorder
=
PictureRecorder
();
final
Canvas
canvas
=
Canvas
(
pictureRecorder
);
screenSize
=
window
.
physicalSize
/
window
.
devicePixelRatio
;
clipSize
=
Size
(
screenSize
.
width
/
2
,
screenSize
.
height
/
5
,
);
final
double
cellWidth
=
screenSize
.
width
/
kColumns
;
final
List
<
Paragraph
>
paragraphs
=
generateLaidOutParagraphs
(
paragraphCount:
500
,
minWordCountPerParagraph:
3
,
maxWordCountPerParagraph:
3
,
widthConstraint:
cellWidth
,
color:
black
,
);
int
paragraphCounter
=
0
;
double
yOffset
=
0.0
;
for
(
int
row
=
0
;
row
<
kRows
;
row
+=
1
)
{
for
(
int
column
=
0
;
column
<
kColumns
;
column
+=
1
)
{
final
double
left
=
cellWidth
*
column
;
canvas
.
save
();
canvas
.
clipRect
(
Rect
.
fromLTWH
(
left
,
yOffset
,
cellWidth
,
20.0
,
));
canvas
.
drawParagraph
(
paragraphs
[
paragraphCounter
%
paragraphs
.
length
],
Offset
(
left
,
yOffset
),
);
canvas
.
restore
();
paragraphCounter
+=
1
;
}
yOffset
+=
kRowHeight
;
}
picture
=
pictureRecorder
.
endRecording
();
}
static
const
String
benchmarkName
=
'dynamic_clip_on_static_picture'
;
Size
screenSize
;
Size
clipSize
;
Picture
picture
;
double
pictureVerticalOffset
=
0.0
;
@override
void
onDrawFrame
(
SceneBuilder
sceneBuilder
)
{
// Render the exact same picture, but offset it as if it's being scrolled.
// This will move the clip along the Y axis in picture's local coordinates
// causing a repaint. If we're not efficient at managing clips and/or
// repaints this will jank (see https://github.com/flutter/flutter/issues/42987).
final
Rect
clip
=
Rect
.
fromLTWH
(
0.0
,
0.0
,
clipSize
.
width
,
clipSize
.
height
);
sceneBuilder
.
pushClipRect
(
clip
);
sceneBuilder
.
pushOffset
(
0.0
,
pictureVerticalOffset
);
sceneBuilder
.
addPicture
(
Offset
.
zero
,
picture
);
sceneBuilder
.
pop
();
sceneBuilder
.
pop
();
pictureVerticalOffset
-=
kScrollDelta
;
}
}
dev/benchmarks/macrobenchmarks/lib/src/web/bench_text_out_of_picture_bounds.dart
View file @
0d077880
...
@@ -33,16 +33,18 @@ class BenchTextOutOfPictureBounds extends SceneBuilderRecorder {
...
@@ -33,16 +33,18 @@ class BenchTextOutOfPictureBounds extends SceneBuilderRecorder {
const
Color
green
=
Color
.
fromARGB
(
255
,
0
,
255
,
0
);
const
Color
green
=
Color
.
fromARGB
(
255
,
0
,
255
,
0
);
// We don't want paragraph generation and layout to pollute benchmark numbers.
// We don't want paragraph generation and layout to pollute benchmark numbers.
singleLineParagraphs
=
_generate
Paragraphs
(
singleLineParagraphs
=
generateLaidOut
Paragraphs
(
paragraphCount:
500
,
paragraphCount:
500
,
minWordCountPerParagraph:
2
,
minWordCountPerParagraph:
2
,
maxWordCountPerParagraph:
5
,
maxWordCountPerParagraph:
4
,
widthConstraint:
window
.
physicalSize
.
width
/
2
,
color:
red
,
color:
red
,
);
);
multiLineParagraphs
=
_generate
Paragraphs
(
multiLineParagraphs
=
generateLaidOut
Paragraphs
(
paragraphCount:
50
,
paragraphCount:
50
,
minWordCountPerParagraph:
30
,
minWordCountPerParagraph:
30
,
maxWordCountPerParagraph:
50
,
maxWordCountPerParagraph:
49
,
widthConstraint:
window
.
physicalSize
.
width
/
2
,
color:
green
,
color:
green
,
);
);
}
}
...
@@ -116,38 +118,4 @@ class BenchTextOutOfPictureBounds extends SceneBuilderRecorder {
...
@@ -116,38 +118,4 @@ class BenchTextOutOfPictureBounds extends SceneBuilderRecorder {
sceneBuilder
.
addPicture
(
Offset
.
zero
,
picture
);
sceneBuilder
.
addPicture
(
Offset
.
zero
,
picture
);
sceneBuilder
.
pop
();
sceneBuilder
.
pop
();
}
}
/// Generates strings and builds pre-laid out paragraphs to be used by the
/// benchmark.
List
<
Paragraph
>
_generateParagraphs
({
int
paragraphCount
,
int
minWordCountPerParagraph
,
int
maxWordCountPerParagraph
,
Color
color
,
})
{
final
List
<
Paragraph
>
strings
=
<
Paragraph
>[];
int
wordPointer
=
0
;
// points to the next word in lipsum to extract
for
(
int
i
=
0
;
i
<
paragraphCount
;
i
++)
{
final
int
wordCount
=
minWordCountPerParagraph
+
_random
.
nextInt
(
maxWordCountPerParagraph
-
minWordCountPerParagraph
);
final
List
<
String
>
string
=
<
String
>[];
for
(
int
j
=
0
;
j
<
wordCount
;
j
++)
{
string
.
add
(
lipsum
[
wordPointer
]);
wordPointer
=
(
wordPointer
+
1
)
%
lipsum
.
length
;
}
final
ParagraphBuilder
builder
=
ParagraphBuilder
(
ParagraphStyle
(
fontFamily:
'sans-serif'
))
..
pushStyle
(
TextStyle
(
color:
color
,
fontSize:
18.0
))
..
addText
(
string
.
join
(
' '
))
..
pop
();
final
Paragraph
paragraph
=
builder
.
build
();
// Fill half the screen.
paragraph
.
layout
(
ParagraphConstraints
(
width:
window
.
physicalSize
.
width
/
2
));
strings
.
add
(
paragraph
);
}
return
strings
;
}
}
}
dev/benchmarks/macrobenchmarks/lib/src/web/recorder.dart
View file @
0d077880
...
@@ -17,14 +17,14 @@ import 'package:flutter/widgets.dart';
...
@@ -17,14 +17,14 @@ import 'package:flutter/widgets.dart';
/// Minimum number of samples collected by a benchmark irrespective of noise
/// Minimum number of samples collected by a benchmark irrespective of noise
/// levels.
/// levels.
const
int
_
kMinSampleCount
=
50
;
const
int
kMinSampleCount
=
50
;
/// Maximum number of samples collected by a benchmark irrespective of noise
/// Maximum number of samples collected by a benchmark irrespective of noise
/// levels.
/// levels.
///
///
/// If the noise doesn't settle down before we reach the max we'll report noisy
/// If the noise doesn't settle down before we reach the max we'll report noisy
/// results assuming the benchmarks is simply always noisy.
/// results assuming the benchmarks is simply always noisy.
const
int
_kMaxSampleCount
=
10
*
_
kMinSampleCount
;
const
int
kMaxSampleCount
=
10
*
kMinSampleCount
;
/// The number of samples used to extract metrics, such as noise, means,
/// The number of samples used to extract metrics, such as noise, means,
/// max/min values.
/// max/min values.
...
@@ -513,7 +513,7 @@ class Profile {
...
@@ -513,7 +513,7 @@ class Profile {
final
Timeseries
timeseries
=
scoreData
[
key
];
final
Timeseries
timeseries
=
scoreData
[
key
];
// Collect enough data points before considering to stop.
// Collect enough data points before considering to stop.
if
(
timeseries
.
count
<
_
kMinSampleCount
)
{
if
(
timeseries
.
count
<
kMinSampleCount
)
{
return
true
;
return
true
;
}
}
...
@@ -522,11 +522,11 @@ class Profile {
...
@@ -522,11 +522,11 @@ class Profile {
// If the timeseries has enough data, stop it, even if it's noisy under
// If the timeseries has enough data, stop it, even if it's noisy under
// the assumption that this benchmark is always noisy and there's nothing
// the assumption that this benchmark is always noisy and there's nothing
// we can do about it.
// we can do about it.
if
(
timeseries
.
count
>
_
kMaxSampleCount
)
{
if
(
timeseries
.
count
>
kMaxSampleCount
)
{
buffer
.
writeln
(
buffer
.
writeln
(
'WARNING: Noise of benchmark "
$name
.
$key
" did not converge below '
'WARNING: Noise of benchmark "
$name
.
$key
" did not converge below '
'
${_ratioToPercent(_kNoiseThreshold)}
. Stopping because it reached the '
'
${_ratioToPercent(_kNoiseThreshold)}
. Stopping because it reached the '
'maximum number of samples
$
_
kMaxSampleCount
. Noise level is '
'maximum number of samples
$kMaxSampleCount
. Noise level is '
'
${_ratioToPercent(timeseries.noise)}
.'
,
'
${_ratioToPercent(timeseries.noise)}
.'
,
);
);
return
false
;
return
false
;
...
...
dev/benchmarks/macrobenchmarks/lib/src/web/test_data.dart
View file @
0d077880
...
@@ -2,6 +2,16 @@
...
@@ -2,6 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
import
'dart:math'
as
math
;
import
'dart:ui'
;
import
'package:meta/meta.dart'
;
// Used to randomize data.
//
// Using constant seed for reproducibility.
final
math
.
Random
_random
=
math
.
Random
(
0
);
/// Random words used by benchmarks that contain text.
/// Random words used by benchmarks that contain text.
final
List
<
String
>
lipsum
=
'Lorem ipsum dolor sit amet, consectetur adipiscing '
final
List
<
String
>
lipsum
=
'Lorem ipsum dolor sit amet, consectetur adipiscing '
'elit. Vivamus ut ligula a neque mattis posuere. Sed suscipit lobortis '
'elit. Vivamus ut ligula a neque mattis posuere. Sed suscipit lobortis '
...
@@ -11,7 +21,7 @@ final List<String> lipsum = 'Lorem ipsum dolor sit amet, consectetur adipiscing
...
@@ -11,7 +21,7 @@ final List<String> lipsum = 'Lorem ipsum dolor sit amet, consectetur adipiscing
'odio vestibulum ultricies. Nunc dolor libero, hendrerit eu urna sit '
'odio vestibulum ultricies. Nunc dolor libero, hendrerit eu urna sit '
'amet, pretium iaculis nulla. Ut porttitor nisl et leo iaculis, vel '
'amet, pretium iaculis nulla. Ut porttitor nisl et leo iaculis, vel '
'fringilla odio pulvinar. Ut eget ligula id odio auctor egestas nec a '
'fringilla odio pulvinar. Ut eget ligula id odio auctor egestas nec a '
'nisl. Aliquam luctus dolor et magna posuere mattis.'
'nisl. Aliquam luctus dolor et magna posuere mattis.
'
'Suspendisse fringilla nisl et massa congue, eget '
'Suspendisse fringilla nisl et massa congue, eget '
'imperdiet lectus porta. Vestibulum sed dui sed dui porta imperdiet ut in risus. '
'imperdiet lectus porta. Vestibulum sed dui sed dui porta imperdiet ut in risus. '
'Fusce diam purus, faucibus id accumsan sit amet, semper a sem. Sed aliquam '
'Fusce diam purus, faucibus id accumsan sit amet, semper a sem. Sed aliquam '
...
@@ -20,3 +30,37 @@ final List<String> lipsum = 'Lorem ipsum dolor sit amet, consectetur adipiscing
...
@@ -20,3 +30,37 @@ final List<String> lipsum = 'Lorem ipsum dolor sit amet, consectetur adipiscing
'pulvinar rhoncus tellus. Nullam vel mauris semper, volutpat tellus at, sagittis '
'pulvinar rhoncus tellus. Nullam vel mauris semper, volutpat tellus at, sagittis '
'lectus. Donec vitae nibh mauris. Morbi posuere sem id eros tristique tempus. '
'lectus. Donec vitae nibh mauris. Morbi posuere sem id eros tristique tempus. '
'Vivamus lacinia sapien neque, eu semper purus gravida ut.'
.
split
(
' '
);
'Vivamus lacinia sapien neque, eu semper purus gravida ut.'
.
split
(
' '
);
/// Generates strings and builds pre-laid out paragraphs to be used by
/// benchmarks.
List
<
Paragraph
>
generateLaidOutParagraphs
({
@required
int
paragraphCount
,
@required
int
minWordCountPerParagraph
,
@required
int
maxWordCountPerParagraph
,
@required
double
widthConstraint
,
@required
Color
color
,
})
{
final
List
<
Paragraph
>
strings
=
<
Paragraph
>[];
int
wordPointer
=
0
;
// points to the next word in lipsum to extract
for
(
int
i
=
0
;
i
<
paragraphCount
;
i
++)
{
final
int
wordCount
=
minWordCountPerParagraph
+
_random
.
nextInt
(
maxWordCountPerParagraph
-
minWordCountPerParagraph
+
1
);
final
List
<
String
>
string
=
<
String
>[];
for
(
int
j
=
0
;
j
<
wordCount
;
j
++)
{
string
.
add
(
lipsum
[
wordPointer
]);
wordPointer
=
(
wordPointer
+
1
)
%
lipsum
.
length
;
}
final
ParagraphBuilder
builder
=
ParagraphBuilder
(
ParagraphStyle
(
fontFamily:
'sans-serif'
))
..
pushStyle
(
TextStyle
(
color:
color
,
fontSize:
18.0
))
..
addText
(
string
.
join
(
' '
))
..
pop
();
final
Paragraph
paragraph
=
builder
.
build
();
// Fill half the screen.
paragraph
.
layout
(
ParagraphConstraints
(
width:
widthConstraint
));
strings
.
add
(
paragraph
);
}
return
strings
;
}
dev/benchmarks/macrobenchmarks/lib/web_benchmarks.dart
View file @
0d077880
...
@@ -12,6 +12,7 @@ import 'package:macrobenchmarks/src/web/bench_text_out_of_picture_bounds.dart';
...
@@ -12,6 +12,7 @@ import 'package:macrobenchmarks/src/web/bench_text_out_of_picture_bounds.dart';
import
'src/web/bench_build_material_checkbox.dart'
;
import
'src/web/bench_build_material_checkbox.dart'
;
import
'src/web/bench_card_infinite_scroll.dart'
;
import
'src/web/bench_card_infinite_scroll.dart'
;
import
'src/web/bench_draw_rect.dart'
;
import
'src/web/bench_draw_rect.dart'
;
import
'src/web/bench_dynamic_clip_on_static_picture.dart'
;
import
'src/web/bench_simple_lazy_text_scroll.dart'
;
import
'src/web/bench_simple_lazy_text_scroll.dart'
;
import
'src/web/bench_text_out_of_picture_bounds.dart'
;
import
'src/web/bench_text_out_of_picture_bounds.dart'
;
import
'src/web/recorder.dart'
;
import
'src/web/recorder.dart'
;
...
@@ -30,6 +31,7 @@ final Map<String, RecorderFactory> benchmarks = <String, RecorderFactory>{
...
@@ -30,6 +31,7 @@ final Map<String, RecorderFactory> benchmarks = <String, RecorderFactory>{
BenchTextOutOfPictureBounds
.
benchmarkName
:
()
=>
BenchTextOutOfPictureBounds
(),
BenchTextOutOfPictureBounds
.
benchmarkName
:
()
=>
BenchTextOutOfPictureBounds
(),
BenchSimpleLazyTextScroll
.
benchmarkName
:
()
=>
BenchSimpleLazyTextScroll
(),
BenchSimpleLazyTextScroll
.
benchmarkName
:
()
=>
BenchSimpleLazyTextScroll
(),
BenchBuildMaterialCheckbox
.
benchmarkName
:
()
=>
BenchBuildMaterialCheckbox
(),
BenchBuildMaterialCheckbox
.
benchmarkName
:
()
=>
BenchBuildMaterialCheckbox
(),
BenchDynamicClipOnStaticPicture
.
benchmarkName
:
()
=>
BenchDynamicClipOnStaticPicture
(),
// Benchmarks that we don't want to run using CanvasKit.
// Benchmarks that we don't want to run using CanvasKit.
if
(!
isCanvasKit
)
...<
String
,
RecorderFactory
>{
if
(!
isCanvasKit
)
...<
String
,
RecorderFactory
>{
...
...
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