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
0866005f
Unverified
Commit
0866005f
authored
Apr 27, 2021
by
Dan Field
Committed by
GitHub
Apr 27, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add benchmark for number of GCs in animated GIF (#81240)
parent
08d7811f
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
179 additions
and
1 deletion
+179
-1
common.dart
dev/benchmarks/macrobenchmarks/lib/common.dart
+1
-0
main.dart
dev/benchmarks/macrobenchmarks/lib/main.dart
+9
-0
animated_image.dart
dev/benchmarks/macrobenchmarks/lib/src/animated_image.dart
+30
-0
pubspec.yaml
dev/benchmarks/macrobenchmarks/pubspec.yaml
+1
-0
animated_image.dart
...enchmarks/macrobenchmarks/test_driver/animated_image.dart
+35
-0
animated_image_test.dart
...arks/macrobenchmarks/test_driver/animated_image_test.dart
+24
-0
animated_image_gc_perf.dart
dev/devicelab/bin/tasks/animated_image_gc_perf.dart
+16
-0
images_demo.dart
...tegration_tests/flutter_gallery/lib/demo/images_demo.dart
+1
-1
prod_builders.json
dev/prod_builders.json
+6
-0
timeline_summary.dart
packages/flutter_driver/lib/src/driver/timeline_summary.dart
+16
-0
timeline_summary_test.dart
...ter_driver/test/src/real_tests/timeline_summary_test.dart
+40
-0
No files found.
dev/benchmarks/macrobenchmarks/lib/common.dart
View file @
0866005f
...
...
@@ -21,6 +21,7 @@ const String kHeavyGridViewRouteName = '/heavy_gridview';
const
String
kSimpleScrollRouteName
=
'/simple_scroll'
;
const
String
kStackSizeRouteName
=
'/stack_size'
;
const
String
kAnimationWithMicrotasksRouteName
=
'/animation_with_microtasks'
;
const
String
kAnimatedImageRouteName
=
'/animated_image'
;
const
String
kScrollableName
=
'/macrobenchmark_listview'
;
...
...
dev/benchmarks/macrobenchmarks/lib/main.dart
View file @
0866005f
...
...
@@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
import
'common.dart'
;
import
'src/animated_image.dart'
;
import
'src/animated_placeholder.dart'
;
import
'src/animation_with_microtasks.dart'
;
import
'src/backdrop_filter.dart'
;
...
...
@@ -58,6 +59,7 @@ class MacrobenchmarksApp extends StatelessWidget {
kSimpleScrollRouteName:
(
BuildContext
context
)
=>
const
SimpleScroll
(),
kStackSizeRouteName:
(
BuildContext
context
)
=>
const
StackSizePage
(),
kAnimationWithMicrotasksRouteName:
(
BuildContext
context
)
=>
const
AnimationWithMicrotasks
(),
kAnimatedImageRouteName:
(
BuildContext
context
)
=>
const
AnimatedImagePage
(),
},
);
}
...
...
@@ -201,6 +203,13 @@ class HomePage extends StatelessWidget {
Navigator
.
pushNamed
(
context
,
kAnimationWithMicrotasksRouteName
);
},
),
ElevatedButton
(
key:
const
Key
(
kAnimatedImageRouteName
),
child:
const
Text
(
'Animated Image'
),
onPressed:
()
{
Navigator
.
pushNamed
(
context
,
kAnimatedImageRouteName
);
},
),
],
),
);
...
...
dev/benchmarks/macrobenchmarks/lib/src/animated_image.dart
0 → 100644
View file @
0866005f
// 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'
;
class
AnimatedImagePage
extends
StatelessWidget
{
const
AnimatedImagePage
({
Key
key
,
this
.
onFrame
})
:
super
(
key:
key
);
final
ValueChanged
<
int
>
onFrame
;
@override
Widget
build
(
BuildContext
context
)
{
return
Scaffold
(
appBar:
AppBar
(
title:
const
Text
(
'Animated Image'
),
),
body:
Image
.
asset
(
'animated_images/animated_flutter_lgtm.gif'
,
package:
'flutter_gallery_assets'
,
frameBuilder:
(
BuildContext
context
,
Widget
child
,
int
/*?*/
frame
,
bool
syncCall
)
{
if
(
onFrame
!=
null
&&
frame
!=
null
)
{
onFrame
(
frame
);
}
return
child
;
},
),
);
}
}
dev/benchmarks/macrobenchmarks/pubspec.yaml
View file @
0866005f
...
...
@@ -81,6 +81,7 @@ dev_dependencies:
flutter
:
uses-material-design
:
true
assets
:
-
packages/flutter_gallery_assets/animated_images/animated_flutter_lgtm.gif
-
packages/flutter_gallery_assets/food/butternut_squash_soup.png
-
packages/flutter_gallery_assets/food/cherry_pie.png
-
assets/999x1000.png
...
...
dev/benchmarks/macrobenchmarks/test_driver/animated_image.dart
0 → 100644
View file @
0866005f
// 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:async'
;
import
'package:flutter/material.dart'
;
import
'package:flutter_driver/driver_extension.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'package:macrobenchmarks/src/animated_image.dart'
;
/// This test is slightly different than most of the other tests in this
/// application, in that it directly instantiates the page we care about and
/// passes a callback. This way, we can make sure to consistently wait for a
/// set number of image frames to render.
Future
<
void
>
main
()
async
{
final
Completer
<
void
>
waiter
=
Completer
<
void
>();
enableFlutterDriverExtension
(
handler:
(
String
request
)
async
{
if
(
request
!=
'waitForAnimation'
)
{
throw
UnsupportedError
(
'Unrecognized request
$request
'
);
}
await
waiter
.
future
;
return
'done'
;
});
runApp
(
MaterialApp
(
home:
AnimatedImagePage
(
onFrame:
(
int
frameNumber
)
{
if
(
frameNumber
==
250
)
{
waiter
.
complete
();
}
},
),
));
}
dev/benchmarks/macrobenchmarks/test_driver/animated_image_test.dart
0 → 100644
View file @
0866005f
// 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_driver/flutter_driver.dart'
;
import
'package:test/test.dart'
hide
TypeMatcher
,
isInstanceOf
;
Future
<
void
>
main
()
async
{
const
String
fileName
=
'large_image_changer'
;
test
(
'Animate for 250 frames'
,
()
async
{
final
FlutterDriver
driver
=
await
FlutterDriver
.
connect
();
await
driver
.
forceGC
();
final
Timeline
timeline
=
await
driver
.
traceAction
(()
async
{
await
driver
.
requestData
(
'waitForAnimation'
);
});
final
TimelineSummary
summary
=
TimelineSummary
.
summarize
(
timeline
);
await
summary
.
writeTimelineToFile
(
fileName
,
pretty:
true
);
await
driver
.
close
();
});
}
dev/devicelab/bin/tasks/animated_image_gc_perf.dart
0 → 100644
View file @
0866005f
// 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_devicelab/framework/adb.dart'
;
import
'package:flutter_devicelab/framework/framework.dart'
;
import
'package:flutter_devicelab/framework/utils.dart'
;
import
'package:flutter_devicelab/tasks/perf_tests.dart'
;
Future
<
void
>
main
()
async
{
deviceOperatingSystem
=
DeviceOperatingSystem
.
android
;
await
task
(
DevToolsMemoryTest
(
'
${flutterDirectory.path}
/dev/benchmarks/macrobenchmarks'
,
'test_driver/animated_image.dart'
,
).
run
);
}
dev/integration_tests/flutter_gallery/lib/demo/images_demo.dart
View file @
0866005f
...
...
@@ -34,7 +34,7 @@ class ImagesDemo extends StatelessWidget {
exampleCodeTag:
'animated_image'
,
demoWidget:
Semantics
(
label:
'Example of animated GIF'
,
child:
Image
.
asset
(
child:
Image
.
asset
(
'animated_images/animated_flutter_lgtm.gif'
,
package:
'flutter_gallery_assets'
,
),
...
...
dev/prod_builders.json
View file @
0866005f
...
...
@@ -324,6 +324,12 @@
"task_name"
:
"linux_large_image_changer_perf_android"
,
"flaky"
:
false
},
{
"name"
:
"Linux animated_image_gc_perf"
,
"repo"
:
"flutter"
,
"task_name"
:
"animated_image_gc_perf"
,
"flaky"
:
true
},
{
"name"
:
"Linux linux_chrome_dev_mode"
,
"repo"
:
"flutter"
,
...
...
packages/flutter_driver/lib/src/driver/timeline_summary.dart
View file @
0866005f
...
...
@@ -95,6 +95,20 @@ class TimelineSummary {
/// The total number of rasterizer cycles recorded in the timeline.
int
countRasterizations
()
=>
_extractGpuRasterizerDrawDurations
().
length
;
/// The total number of old generation garbage collections recorded in the timeline.
int
oldGenerationGarbageCollections
()
{
return
_timeline
.
events
!.
where
((
TimelineEvent
event
)
{
return
event
.
category
==
'GC'
&&
event
.
name
==
'CollectOldGeneration'
;
}).
length
;
}
/// The total number of new generation garbage collections recorded in the timeline.
int
newGenerationGarbageCollections
()
{
return
_timeline
.
events
!.
where
((
TimelineEvent
event
)
{
return
event
.
category
==
'GC'
&&
event
.
name
==
'CollectNewGeneration'
;
}).
length
;
}
/// Encodes this summary as JSON.
///
/// Data ends with "_time_millis" means time in milliseconds and numbers in
...
...
@@ -176,6 +190,8 @@ class TimelineSummary {
'missed_frame_rasterizer_budget_count'
:
computeMissedFrameRasterizerBudgetCount
(),
'frame_count'
:
countFrames
(),
'frame_rasterizer_count'
:
countRasterizations
(),
'new_gen_gc_count'
:
newGenerationGarbageCollections
(),
'old_gen_gc_count'
:
oldGenerationGarbageCollections
(),
'frame_build_times'
:
_extractFrameDurations
()
.
map
<
int
>((
Duration
duration
)
=>
duration
.
inMicroseconds
)
.
toList
(),
...
...
packages/flutter_driver/test/src/real_tests/timeline_summary_test.dart
View file @
0866005f
...
...
@@ -95,6 +95,38 @@ void main() {
'ts'
:
timeStamp
,
};
List
<
Map
<
String
,
dynamic
>>
newGenGC
(
int
count
)
=>
List
<
Map
<
String
,
dynamic
>>.
filled
(
count
,
<
String
,
dynamic
>{
'name'
:
'CollectNewGeneration'
,
'cat'
:
'GC'
,
'tid'
:
19695
,
'pid'
:
19650
,
'ts'
:
358849612473
,
'tts'
:
476761
,
'ph'
:
'B'
,
'args'
:
<
String
,
dynamic
>{
'isolateGroupId'
:
'isolateGroups/10824099774666259225'
,
},
},
);
List
<
Map
<
String
,
dynamic
>>
oldGenGC
(
int
count
)
=>
List
<
Map
<
String
,
dynamic
>>.
filled
(
count
,
<
String
,
dynamic
>{
'name'
:
'CollectOldGeneration'
,
'cat'
:
'GC'
,
'tid'
:
19695
,
'pid'
:
19650
,
'ts'
:
358849612473
,
'tts'
:
476761
,
'ph'
:
'B'
,
'args'
:
<
String
,
dynamic
>{
'isolateGroupId'
:
'isolateGroups/10824099774666259225'
,
},
},
);
List
<
Map
<
String
,
dynamic
>>
rasterizeTimeSequenceInMillis
(
List
<
int
>
sequence
)
{
final
List
<
Map
<
String
,
dynamic
>>
result
=
<
Map
<
String
,
dynamic
>>[];
int
t
=
0
;
...
...
@@ -388,6 +420,8 @@ void main() {
begin
(
1000
),
end
(
19000
),
begin
(
19000
),
end
(
29000
),
begin
(
29000
),
end
(
49000
),
...
newGenGC
(
4
),
...
oldGenGC
(
5
),
frameBegin
(
1000
),
frameEnd
(
18000
),
frameBegin
(
19000
),
frameEnd
(
28000
),
frameBegin
(
29000
),
frameEnd
(
48000
),
...
...
@@ -405,6 +439,8 @@ void main() {
'missed_frame_rasterizer_budget_count'
:
2
,
'frame_count'
:
3
,
'frame_rasterizer_count'
:
3
,
'new_gen_gc_count'
:
4
,
'old_gen_gc_count'
:
5
,
'frame_build_times'
:
<
int
>[
17000
,
9000
,
19000
],
'frame_rasterizer_times'
:
<
int
>[
18000
,
10000
,
20000
],
'frame_begin_times'
:
<
int
>[
0
,
18000
,
28000
],
...
...
@@ -475,6 +511,8 @@ void main() {
lagBegin
(
1000
,
4
),
lagEnd
(
2000
,
4
),
lagBegin
(
1200
,
12
),
lagEnd
(
2400
,
12
),
lagBegin
(
4200
,
8
),
lagEnd
(
9400
,
8
),
...
newGenGC
(
4
),
...
oldGenGC
(
5
),
cpuUsage
(
5000
,
20
),
cpuUsage
(
5010
,
60
),
memoryUsage
(
6000
,
20
,
40
),
memoryUsage
(
6100
,
30
,
45
),
platformVsync
(
7000
),
vsyncCallback
(
7500
),
...
...
@@ -494,6 +532,8 @@ void main() {
'missed_frame_rasterizer_budget_count'
:
2
,
'frame_count'
:
3
,
'frame_rasterizer_count'
:
3
,
'new_gen_gc_count'
:
4
,
'old_gen_gc_count'
:
5
,
'frame_build_times'
:
<
int
>[
17000
,
9000
,
19000
],
'frame_rasterizer_times'
:
<
int
>[
18000
,
10000
,
20000
],
'frame_begin_times'
:
<
int
>[
0
,
18000
,
28000
],
...
...
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