1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
[<-- Back to README.md](../README.md)
# Creating custom benchmarks
Sometimes an existing test doesn't cover your hacks to qt, or maybe you're adding new functionality,
either way, creating new benchmarks is easy. ~Here's how!~
## The fundamentals of QMLBench
When running qmlbench in `frame-count shell` (default mode), a static count of operations is
performed for each frame rendered. QMLbench renders as quickly as possible over a 20 second
(default) period counting the total frames rendered during that period. This is the 'score'.
In this way, a benchmark should be defined to perform as many operations as possible without
hanging qmlbench, typically managing to run at a few frames-per-second on mid-grade hardware.
If this rule is observed, a benchmark should be able to run on low-grade embedded hardware without
timing out and hanging, as well as on high-end hardware without acheiving 60fps
(the typical soft cap if vsync cannot be disabled).
## A sample file
import QtQuick 2.0
import QmlBench 1.0
// Tests the creation of rectangles with *NO* alpha channel.
// Compare with delegates_rect_blended & delegates_rect_radius
CreationBenchmark {
id: root;
count: 50;
staticCount: 2500;
delegate: Rectangle {
x: QmlBench.getRandom() * (root.width - width)
y: QmlBench.getRandom() * (root.height - height)
width: 30
height: 15
color: "steelblue"
}
}
## The root level declarations
In the example above, we're testing the creation speed of the `Rectangle` delegate, so we're using `CreationBenchmark`.
There are three types of rool level declarations allowed:
- Benchmark
- The basic QMLBench type.
- Good for testing performance of operations with fixed durations, such as animations.
- Provides the `count` and `staticCount` properties.
- Provides a tick property `t` from 0 to 1, lasting 1000ms that benchmarks can access.
- CreationBenchmark
- Inherits Benchmark
- Creates `count` instances of an object before displaying the rendered frame.
- Destroys all items and recreates them each frame.
- Item (Inherited from QtBase)
- must declare the following manually
```
id: root;
property int count: your_count_here;
property int staticCount: your_static_count_here;
property real t;
NumberAnimation on t { from: 0; to: 1; duration: your_ticker_duration_in_ms; loops: Animation.Infinite }
```
## Count and StaticCount
In general, it is good practice to set both values so the benchmark can be used with any shell type.
### count
Used in `susained-fps shell` mode. The benchmark will alter this value trying to achieve 60fps
(or rather, the screen's refresh rate). Set this value to as a starting point for the benchmark to
try first.
### staticCount
Used in all `static` shell types. This is the count of objects to create on startup.
- If using CreationBenchmark root type, this is the count of objects to create each frame.
- If using Benchmark, this is the count of objects to create at the start of the benchmark run.
## Item delegates (Creation Benchmarks)
In the code sample above, the `delegate` (a property of CreationBenchmark) is defined as a
Rectangle with a fixed size and random position, shaded a single color with no transparency.
- This `delegate` will be repeated in the render window in accordance with the properties `count`
or `staticCount`, for a given shell type.
- The delegates will be destroyed and regenerated for each frame rendered.
## Repeaters (Non-creation benchmarks)
Let's take a look at a new code sample. For this benchmark, we're repeating an operation `count`
times using `Repeater` at the benchmark outset, and continuing to render for the duration of the test.
import QtQuick 2.2
import QmlBench 1.0
// Move images around using Animation types, to be compared with a number of
// other similar ways to move them around.
Benchmark {
id: root;
count: 500
staticCount: 20000
Repeater {
model: root.count
Image {
source: "../../../../shared/butterfly-wide.png"
x: QmlBench.getRandom() * (root.width - width)
y: QmlBench.getRandom() * (root.height - height)
width: 40
height: 40
SequentialAnimation on rotation {
NumberAnimation { from: -10; to: 10; duration: 500; easing.type: Easing.InOutCubic }
NumberAnimation { from: 10; to: -10; duration: 500; easing.type: Easing.InOutCubic }
loops: Animation.Infinite
}
}
}
}
In this case, the image `butterfly-wide.png` is being randomly placed in the render window, and has
an animation applied on `rotation`, looping infinitely. The image and animation will be repeated 500
times, resulting in 500 randomly placed, rotating images for the duration of the benchmark run.
- Multiple `Repeaters` can be added if necessary, though it's recommended to test the smallest
possible operation specific to your change.
|