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
af21e74f
Unverified
Commit
af21e74f
authored
Mar 25, 2020
by
Mouad Debbar
Committed by
GitHub
Mar 25, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[web] Write benchmarks to measure canvas-based text layout (#52434)
parent
1cbbe726
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
139 additions
and
23 deletions
+139
-23
bench_text_layout.dart
...hmarks/macrobenchmarks/lib/src/web/bench_text_layout.dart
+134
-20
recorder.dart
dev/benchmarks/macrobenchmarks/lib/src/web/recorder.dart
+1
-1
web_benchmarks.dart
dev/benchmarks/macrobenchmarks/lib/web_benchmarks.dart
+4
-2
No files found.
dev/benchmarks/macrobenchmarks/lib/src/web/bench_text_layout.dart
View file @
af21e74f
...
...
@@ -2,37 +2,144 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:html'
as
html
;
import
'dart:js_util'
as
js_util
;
import
'dart:math'
;
import
'dart:ui'
;
import
'package:meta/meta.dart'
;
import
'recorder.dart'
;
int
_counter
=
0
;
const
String
chars
=
'1234567890'
'abcdefghijklmnopqrstuvwxyz'
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
'!@#%^&()[]{}<>,./?;:"`~-_=+|'
;
Paragraph
_generateParagraph
(
)
{
final
ParagraphBuilder
builder
=
ParagraphBuilder
(
ParagraphStyle
(
fontFamily:
'sans-serif'
))
..
pushStyle
(
TextStyle
(
fontSize:
12.0
))
..
addText
(
'
$_counter
Lorem ipsum dolor sit amet, consectetur adipiscing elit, '
'sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
,
);
_counter
++;
return
builder
.
build
();
String
_randomize
(
String
text
)
{
return
text
.
replaceAllMapped
(
'*'
,
// Passing a seed so the results are reproducible.
(
_
)
=>
chars
[
Random
(
0
).
nextInt
(
chars
.
length
)],
);
}
class
ParagraphGenerator
{
int
_counter
=
0
;
/// Randomizes the given [text] and creates a paragraph with a unique
/// font-size so that the engine doesn't reuse a cached ruler.
Paragraph
generate
(
String
text
,
{
int
maxLines
,
bool
hasEllipsis
=
false
,
})
{
final
ParagraphBuilder
builder
=
ParagraphBuilder
(
ParagraphStyle
(
fontFamily:
'sans-serif'
,
maxLines:
maxLines
,
ellipsis:
hasEllipsis
?
'...'
:
null
,
))
// Start from a font-size of 8.0 and go up by 0.01 each time.
..
pushStyle
(
TextStyle
(
fontSize:
8.0
+
_counter
*
0.01
))
..
addText
(
_randomize
(
text
));
_counter
++;
return
builder
.
build
();
}
}
/// Sends a platform message to the web engine to enable/disable the usage of
/// the new canvas-based text measurement implementation.
void
_useCanvasText
(
bool
useCanvasText
)
{
js_util
.
callMethod
(
html
.
window
,
'_flutter_internal_update_experiment'
,
<
dynamic
>[
'useCanvasText'
,
useCanvasText
],
);
}
/// Repeatedly lays out a paragraph using the DOM measurement approach.
///
/// Creates a different paragraph each time in order to avoid hitting the cache.
class
BenchTextDomLayout
extends
RawRecorder
{
BenchTextDomLayout
()
:
super
(
name:
benchmarkName
);
class
BenchTextLayout
extends
RawRecorder
{
BenchTextLayout
({
@required
this
.
useCanvas
})
:
super
(
name:
useCanvas
?
canvasBenchmarkName
:
domBenchmarkName
);
static
const
String
domBenchmarkName
=
'text_dom_layout'
;
static
const
String
canvasBenchmarkName
=
'text_canvas_layout'
;
static
const
String
benchmarkName
=
'text_dom_layout'
;
final
ParagraphGenerator
generator
=
ParagraphGenerator
();
/// Whether to use the new canvas-based text measurement implementation.
final
bool
useCanvas
;
static
const
String
singleLineText
=
'*** ** ****'
;
static
const
String
multiLineText
=
'*** ****** **** *** ******** * *** '
'******* **** ********** *** ******* '
'**** ***** *** ******** *** ********* '
'** * *** ******* ***********'
;
@override
void
body
(
Profile
profile
)
{
final
Paragraph
paragraph
=
_generateParagraph
();
profile
.
record
(
'layout'
,
()
{
paragraph
.
layout
(
const
ParagraphConstraints
(
width:
double
.
infinity
));
_useCanvasText
(
useCanvas
);
recordParagraphOperations
(
profile:
profile
,
paragraph:
generator
.
generate
(
singleLineText
),
text:
singleLineText
,
keyPrefix:
'single_line'
,
maxWidth:
800.0
,
);
recordParagraphOperations
(
profile:
profile
,
paragraph:
generator
.
generate
(
multiLineText
),
text:
multiLineText
,
keyPrefix:
'multi_line'
,
maxWidth:
200.0
,
);
recordParagraphOperations
(
profile:
profile
,
paragraph:
generator
.
generate
(
multiLineText
,
maxLines:
2
),
text:
multiLineText
,
keyPrefix:
'max_lines'
,
maxWidth:
200.0
,
);
recordParagraphOperations
(
profile:
profile
,
paragraph:
generator
.
generate
(
multiLineText
,
hasEllipsis:
true
),
text:
multiLineText
,
keyPrefix:
'ellipsis'
,
maxWidth:
200.0
,
);
_useCanvasText
(
null
);
}
void
recordParagraphOperations
({
@required
Profile
profile
,
@required
Paragraph
paragraph
,
@required
String
text
,
@required
String
keyPrefix
,
@required
double
maxWidth
,
})
{
profile
.
record
(
'
$keyPrefix
.layout'
,
()
{
paragraph
.
layout
(
ParagraphConstraints
(
width:
maxWidth
));
});
profile
.
record
(
'
$keyPrefix
.getBoxesForRange'
,
()
{
for
(
int
start
=
0
;
start
<
text
.
length
;
start
+=
3
)
{
for
(
int
end
=
start
+
1
;
end
<
text
.
length
;
end
*=
2
)
{
paragraph
.
getBoxesForRange
(
start
,
end
);
}
}
});
profile
.
record
(
'
$keyPrefix
.getPositionForOffset'
,
()
{
for
(
double
dx
=
0.0
;
dx
<
paragraph
.
width
;
dx
+=
10.0
)
{
for
(
double
dy
=
0.0
;
dy
<
paragraph
.
height
;
dy
+=
10.0
)
{
paragraph
.
getPositionForOffset
(
Offset
(
dx
,
dy
));
}
}
});
}
}
...
...
@@ -42,10 +149,15 @@ class BenchTextDomLayout extends RawRecorder {
/// Uses the same paragraph content to make sure we hit the cache. It doesn't
/// use the same paragraph instance because the layout method will shortcircuit
/// in that case.
class
BenchTextDomCachedLayout
extends
RawRecorder
{
BenchTextDomCachedLayout
()
:
super
(
name:
benchmarkName
);
class
BenchTextCachedLayout
extends
RawRecorder
{
BenchTextCachedLayout
({
@required
this
.
useCanvas
})
:
super
(
name:
useCanvas
?
canvasBenchmarkName
:
domBenchmarkName
);
static
const
String
domBenchmarkName
=
'text_dom_cached_layout'
;
static
const
String
canvasBenchmarkName
=
'text_canvas_cached_layout'
;
static
const
String
benchmarkName
=
'text_dom_cached_layout'
;
/// Whether to use the new canvas-based text measurement implementation.
final
bool
useCanvas
;
final
ParagraphBuilder
builder
=
ParagraphBuilder
(
ParagraphStyle
(
fontFamily:
'sans-serif'
))
...
...
@@ -57,9 +169,11 @@ class BenchTextDomCachedLayout extends RawRecorder {
@override
void
body
(
Profile
profile
)
{
_useCanvasText
(
useCanvas
);
final
Paragraph
paragraph
=
builder
.
build
();
profile
.
record
(
'layout'
,
()
{
paragraph
.
layout
(
const
ParagraphConstraints
(
width:
double
.
infinity
));
});
_useCanvasText
(
null
);
}
}
dev/benchmarks/macrobenchmarks/lib/src/web/recorder.dart
View file @
af21e74f
...
...
@@ -518,7 +518,7 @@ class Profile {
}
buffer
.
writeln
(
'SUCCESS: Benchmark converged below
${_ratioToPercent(_kNoiseThreshold)}
. '
'SUCCESS: Benchmark
"
$name
.
$key
"
converged below
${_ratioToPercent(_kNoiseThreshold)}
. '
'Noise level is
${_ratioToPercent(timeseries.noise)}
.'
,
);
return
false
;
...
...
dev/benchmarks/macrobenchmarks/lib/web_benchmarks.dart
View file @
af21e74f
...
...
@@ -33,8 +33,10 @@ final Map<String, RecorderFactory> benchmarks = <String, RecorderFactory>{
// Benchmarks that we don't want to run using CanvasKit.
if
(!
isCanvasKit
)
...<
String
,
RecorderFactory
>{
BenchTextDomLayout
.
benchmarkName
:
()
=>
BenchTextDomLayout
(),
BenchTextDomCachedLayout
.
benchmarkName
:
()
=>
BenchTextDomCachedLayout
(),
BenchTextLayout
.
domBenchmarkName
:
()
=>
BenchTextLayout
(
useCanvas:
false
),
BenchTextLayout
.
canvasBenchmarkName
:
()
=>
BenchTextLayout
(
useCanvas:
true
),
BenchTextCachedLayout
.
domBenchmarkName
:
()
=>
BenchTextCachedLayout
(
useCanvas:
false
),
BenchTextCachedLayout
.
canvasBenchmarkName
:
()
=>
BenchTextCachedLayout
(
useCanvas:
true
),
}
};
...
...
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