Skip to content

Commit 37209a9

Browse files
author
Unity Technologies
committed
com.unity.test-framework.performance@2.4.1-preview
## [2.4.1] - 2020-11-05 Metadata collection was made public ## [2.4.0] - 2020-09-16 Upgrade json dependency to release version Reduced overhead introduced when running tests Performance Test Report window updates: Added CSV export option. Added monitoring of results file timestemp to support auto refresh when a new file is found. Added display of timestamp of last loaded results file. Added option to sort test report window by order the tests ran in (index). This is now the default. Added min and max to the table. Improve titles and tooltips on columns ## [2.3.1] - 2020-07-01 Fix overhead introduced with Measure.Method no longer calculates execution time of Setup and Cleanup changes
1 parent 3f9805e commit 37209a9

File tree

12 files changed

+573
-209
lines changed

12 files changed

+573
-209
lines changed

CHANGELOG.md

Lines changed: 78 additions & 61 deletions
Large diffs are not rendered by default.

Documentation~/index.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,19 @@ The Performance Testing Extension is intended to be used with, and complement, t
1111

1212
To install the Performance Testing Extension package
1313
1. Open the `manifest.json` file for your Unity project (located in the YourProject/Packages directory) in a text editor
14-
2. Add `"com.unity.test-framework.performance": "2.3.1-preview",` to the dependencies
14+
2. Add `"com.unity.test-framework.performance": "2.4.0",` to the dependencies
1515
3. Save the manifest.json file
1616
4. Verify the Performance Testing Extension is now installed opening the Unity Package Manager window
1717

1818
To access performance testing apis add `Unity.PerformanceTesting` to your assembly definition references section.
1919

20+
Performance package will need to be preserved in link.xml file if Managed stripping level is enabled in Player settings. This is nesesarry for console and mobile platforms.
21+
22+
```xml
23+
<linker>
24+
<assembly fullname="Unity.PerformanceTesting" preserve="all"/>
25+
</linker>
26+
```
2027

2128
## Test Attributes
2229
**[Performance]** - Use this with `Test` and `UnityTest` attributes. It will initialize necessary test setup for performance tests.
@@ -61,6 +68,9 @@ This will execute the provided method, sampling performance using the following
6168
* **IterationsPerMeasurement(int n)** - number of method executions per measurement to use. If this value is not specified, the method will be executed as many times as possible until approximately 100 ms has elapsed.
6269
* **SampleGroup(string name)** - by default the measurement name will be "Time", this allows you to override it
6370
* **GC()** - if specified, will measure the total number of Garbage Collection allocation calls.
71+
* **SetUp(Action action)** - is called every iteration before executing the method. Setup time is not measured.
72+
* **CleanUp(Action action)** - is called every iteration after the execution of the method. Cleanup time is not measured.
73+
6474

6575
#### Example 1: Simple method measurement using default values
6676

@@ -83,6 +93,8 @@ public void Test()
8393
.MeasurementCount(10)
8494
.IterationsPerMeasurement(5)
8595
.GC()
96+
.SetUp(()=> {/*setup code*/})
97+
.CleanUp(()=> {/*cleanup code*/})
8698
.Run();
8799
}
88100
```
@@ -177,7 +189,7 @@ public void Test()
177189

178190
### Measure.ProfilerMarkers()
179191

180-
Used to record profiler markers. Profiler marker timings will be recorded automatically and sampled within the scope of the `using` statement. Names should match profiler marker labels. Note that deep and editor profiling are not available. Profiler markers created using `Profiler.BeginSample()` are not supported, switch to `ProfilerMarker` if possible.
192+
Used to record profiler markers. Profiler marker timings will be recorded automatically and sampled within the scope of the `using` statement. Names should match profiler marker labels. Profiler markers are sampled once per frame. Sampling the same profiler marker per frame will result in the sum of all invocations. Note that deep and editor profiling is not available. Profiler markers created using `Profiler.BeginSample()` are not supported, switch to `ProfilerMarker` if possible.
181193

182194
#### Example 1: Measuring profiler markers in a scope
183195

@@ -560,4 +572,4 @@ For compairing performance data between runs use [Unity Performance Benchmark Re
560572
Measure.Custom(allocated, Profiler.GetTotalAllocatedMemoryLong() / 1048576f);
561573
Measure.Custom(reserved, Profiler.GetTotalReservedMemoryLong() / 1048576f);
562574
}
563-
```
575+
```

Editor/TestReportGraph/TestListTable.cs

Lines changed: 101 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -11,43 +11,57 @@ namespace Unity.PerformanceTesting
1111
{
1212
class TestListTableItem : TreeViewItem
1313
{
14+
public int index;
1415
public TestResult test;
1516
public double deviation;
1617
public double standardDeviation;
1718
public double median;
19+
public double min;
20+
public double max;
1821

1922
public TestListTableItem(int id, int depth, string displayName, TestResult test)
2023
: base(id, depth,
2124
displayName)
2225
{
2326
this.test = test;
2427

28+
index = id;
2529
deviation = 0f;
2630
if (test != null)
2731
{
2832
foreach (var sample in test.SampleGroups)
2933
{
3034
if (sample.Name == "Time")
3135
{
32-
deviation = sample.StandardDeviation;
36+
standardDeviation = sample.StandardDeviation;
3337
median = sample.Median;
38+
min = sample.Min;
39+
max = sample.Max;
40+
41+
deviation = standardDeviation / median;
3442
break;
3543
}
3644

3745
if (sample.Samples.Count <= 1)
3846
{
47+
standardDeviation = sample.StandardDeviation;
3948
median = sample.Median;
49+
min = sample.Min;
50+
max = sample.Max;
51+
52+
deviation = standardDeviation / median;
4053
break;
4154
}
4255

43-
if (sample.StandardDeviation > deviation)
44-
standardDeviation = sample.StandardDeviation;
45-
4656
double thisDeviation = sample.StandardDeviation / sample.Median;
4757
if (thisDeviation > deviation)
4858
{
49-
deviation = thisDeviation;
59+
standardDeviation = sample.StandardDeviation;
5060
median = sample.Median;
61+
min = sample.Min;
62+
max = sample.Max;
63+
64+
deviation = thisDeviation;
5165
}
5266
}
5367
}
@@ -64,30 +78,39 @@ class TestListTable : TreeView
6478
// All columns
6579
public enum MyColumns
6680
{
81+
Index,
6782
Name,
6883
SampleCount,
6984
StandardDeviation,
7085
Deviation,
71-
Median
86+
Median,
87+
Min,
88+
Max,
7289
}
7390

7491
public enum SortOption
7592
{
93+
Index,
7694
Name,
7795
SampleCount,
7896
StandardDeviation,
7997
Deviation,
80-
Median
98+
Median,
99+
Min,
100+
Max,
81101
}
82102

83103
// Sort options per column
84104
SortOption[] m_SortOptions =
85105
{
106+
SortOption.Index,
86107
SortOption.Name,
87108
SortOption.SampleCount,
88109
SortOption.StandardDeviation,
89110
SortOption.Deviation,
90-
SortOption.Median
111+
SortOption.Median,
112+
SortOption.Min,
113+
SortOption.Max,
91114
};
92115

93116
public TestListTable(TreeViewState state, MultiColumnHeader multicolumnHeader,
@@ -201,6 +224,9 @@ void SortByMultipleColumns()
201224

202225
switch (sortOption)
203226
{
227+
case SortOption.Index:
228+
orderedQuery = orderedQuery.ThenBy(l => l.index, ascending);
229+
break;
204230
case SortOption.Name:
205231
orderedQuery = orderedQuery.ThenBy(l => l.displayName, ascending);
206232
break;
@@ -216,6 +242,12 @@ void SortByMultipleColumns()
216242
case SortOption.Median:
217243
orderedQuery = orderedQuery.ThenBy(l => l.median, ascending);
218244
break;
245+
case SortOption.Min:
246+
orderedQuery = orderedQuery.ThenBy(l => l.min, ascending);
247+
break;
248+
case SortOption.Max:
249+
orderedQuery = orderedQuery.ThenBy(l => l.max, ascending);
250+
break;
219251
}
220252
}
221253

@@ -228,6 +260,8 @@ IOrderedEnumerable<TestListTableItem> InitialOrder(IEnumerable<TestListTableItem
228260
bool ascending = multiColumnHeader.IsSortedAscending(history[0]);
229261
switch (sortOption)
230262
{
263+
case SortOption.Index:
264+
return myTypes.Order(l => l.index, ascending);
231265
case SortOption.Name:
232266
return myTypes.Order(l => l.displayName, ascending);
233267
case SortOption.SampleCount:
@@ -238,13 +272,17 @@ IOrderedEnumerable<TestListTableItem> InitialOrder(IEnumerable<TestListTableItem
238272
return myTypes.Order(l => l.standardDeviation, ascending);
239273
case SortOption.Median:
240274
return myTypes.Order(l => l.median, ascending);
275+
case SortOption.Min:
276+
return myTypes.Order(l => l.min, ascending);
277+
case SortOption.Max:
278+
return myTypes.Order(l => l.max, ascending);
241279
default:
242280
Assert.IsTrue(false, "Unhandled enum");
243281
break;
244282
}
245283

246284
// default
247-
return myTypes.Order(l => l.displayName, ascending);
285+
return myTypes.Order(l => l.index, ascending);
248286
}
249287

250288
protected override void RowGUI(RowGUIArgs args)
@@ -264,11 +302,11 @@ void CellGUI(Rect cellRect, TestListTableItem item, MyColumns column, ref RowGUI
264302

265303
switch (column)
266304
{
305+
case MyColumns.Index:
306+
EditorGUI.LabelField(cellRect, string.Format("{0}", item.index));
307+
break;
267308
case MyColumns.Name:
268-
{
269-
args.rowRect = cellRect;
270-
base.RowGUI(args);
271-
}
309+
EditorGUI.LabelField(cellRect, string.Format("{0}", item.displayName));
272310
break;
273311
case MyColumns.SampleCount:
274312
EditorGUI.LabelField(cellRect, string.Format("{0}", item.test.SampleGroups.Count));
@@ -282,6 +320,12 @@ void CellGUI(Rect cellRect, TestListTableItem item, MyColumns column, ref RowGUI
282320
case MyColumns.Median:
283321
EditorGUI.LabelField(cellRect, string.Format("{0:f2}", item.median));
284322
break;
323+
case MyColumns.Min:
324+
EditorGUI.LabelField(cellRect, string.Format("{0:f2}", item.min));
325+
break;
326+
case MyColumns.Max:
327+
EditorGUI.LabelField(cellRect, string.Format("{0:f2}", item.max));
328+
break;
285329
}
286330
}
287331

@@ -293,37 +337,54 @@ protected override bool CanMultiSelect(TreeViewItem item)
293337
return false;
294338
}
295339

340+
struct HeaderData
341+
{
342+
public readonly GUIContent content;
343+
public readonly float width;
344+
public readonly float minWidth;
345+
public readonly bool autoResize;
346+
public readonly bool allowToggleVisibility;
347+
public readonly bool ascending;
348+
349+
public HeaderData(string name, string tooltip = "", float width = 100, float minWidth = 50, bool autoResize = true, bool allowToggleVisibility = true, bool ascending = false)
350+
{
351+
content = new GUIContent(name, tooltip);
352+
this.width = width;
353+
this.minWidth = minWidth;
354+
this.autoResize = autoResize;
355+
this.allowToggleVisibility = allowToggleVisibility;
356+
this.ascending = ascending;
357+
}
358+
}
359+
296360
public static MultiColumnHeaderState CreateDefaultMultiColumnHeaderState(float treeViewWidth)
297361
{
298362
var columnList = new List<MultiColumnHeaderState.Column>();
299-
columnList.Add(new MultiColumnHeaderState.Column
363+
HeaderData[] headerData = new HeaderData[]
300364
{
301-
headerContent = new GUIContent("Name"),
302-
headerTextAlignment = TextAlignment.Left,
303-
sortedAscending = true,
304-
sortingArrowAlignment = TextAlignment.Left,
305-
width = 600,
306-
minWidth = 100,
307-
autoResize = false,
308-
allowToggleVisibility = false
309-
});
310-
string[] names = { "Sample Groups", "Standard Deviation", "Deviation", "Median" };
311-
foreach (var name in names)
365+
new HeaderData("Index", "Ordering from the test run", width : 40, minWidth : 50),
366+
new HeaderData("Name", "Name of test", width : 500, minWidth : 100, autoResize : false, allowToggleVisibility : false, ascending : true),
367+
new HeaderData("Groups", "Number of Sample Groups", width : 60, minWidth : 50),
368+
new HeaderData("SD", "Standard Deviation"), // (of sample group with largest deviation)
369+
new HeaderData("Deviation", "Standard Deviation / Median"),
370+
new HeaderData("Median", "Median value"),
371+
new HeaderData("Min", "Min value"),
372+
new HeaderData("Max", "Max value"),
373+
};
374+
foreach (var header in headerData)
312375
{
313-
var column = new MultiColumnHeaderState.Column
376+
columnList.Add(new MultiColumnHeaderState.Column
314377
{
315-
headerContent = new GUIContent(name),
378+
headerContent = header.content,
316379
headerTextAlignment = TextAlignment.Left,
317-
sortedAscending = true,
380+
sortedAscending = header.ascending,
318381
sortingArrowAlignment = TextAlignment.Left,
319-
width = 100,
320-
minWidth = 50,
321-
autoResize = true
322-
};
323-
columnList.Add(column);
324-
}
325-
326-
;
382+
width = header.width,
383+
minWidth = header.minWidth,
384+
autoResize = header.autoResize,
385+
allowToggleVisibility = header.allowToggleVisibility
386+
});
387+
};
327388
var columns = columnList.ToArray();
328389

329390
Assert.AreEqual(columns.Length, Enum.GetValues(typeof(MyColumns)).Length,
@@ -332,11 +393,14 @@ public static MultiColumnHeaderState CreateDefaultMultiColumnHeaderState(float t
332393
var state = new MultiColumnHeaderState(columns);
333394
state.visibleColumns = new int[]
334395
{
396+
(int)MyColumns.Index,
335397
(int)MyColumns.Name,
336398
(int)MyColumns.SampleCount,
337399
(int)MyColumns.Deviation,
338400
(int)MyColumns.StandardDeviation,
339-
(int)MyColumns.Median
401+
(int)MyColumns.Median,
402+
(int)MyColumns.Min,
403+
(int)MyColumns.Max,
340404
};
341405
return state;
342406
}

0 commit comments

Comments
 (0)