我怎么能运行我的性能测试超过十次?
How can I run my performance tests more than ten times?
默认情况下,Xcodes 性能测试是 运行 十次,我的结果是这十次测试的平均值。问题是每次 运行 平均结果都会有很大差异,所以我必须 运行 测试至少五次才能获得收敛结果。这既乏味又费时;有没有办法将 XCode 或单元测试本身配置为 运行 十次以上?
简答:不,目前没有暴露的接口允许一个measure block超过十次。
较长的答案:不,但是有一个接口公开来修改度量块的某些指标。默认指标位于从 defaultPerformanceMetrics
返回的字符串数组中。目前似乎只支持一种指标:XCTPerformanceMetric_WallClockTime
。这仅指定了一个性能指标,该指标记录调用性能测试的 startMeasuring()
和 stopMeasuring()
方法之间的时间(以秒为单位),而不是块 运行.[=15= 的次数]
XCTestCase 的 class 转储公开了此方法:
- (void)_recordValues:(id)arg1 forPerformanceMetricID:(id)arg2 name:(id)arg3 unitsOfMeasurement:(id)arg4 baselineName:(id)arg5 baselineAverage:(id)arg6 maxPercentRegression:(id)arg7 maxPercentRelativeStandardDeviation:(id)arg8 maxRegression:(id)arg9 maxStandardDeviation:(id)arg10 file:(id)arg11 line:(unsigned long long)arg12;
调配此方法时,第一个参数 (arg1) 具有 10 个持续时间:
["0.003544568",
"0.003456569",
"0.003198263",
"0.003257955",
"0.003508724",
"0.003454298",
"0.003461192",
"0.00423787",
"0.003359195",
"0.003335757"]
我在将其传递回原始实现之前在此列表的末尾添加了 4 个新值(1.0、2.0、3.0、4.0),但不幸的是观察到一个不同的 class,XCTestLog
, 有一个内部完整性检查被触发:
Assertion failure in +[XCTestLog _messageForTest:didMeasureValues:forPerformanceMetricID:name:unitsOfMeasurement:baselineName:baselineAverage:maxPercentRegression:maxPercentRelativeStandardDeviation:maxRegression:maxStandardDeviation:file:line:]
caught "NSInternalInconsistencyException", "Performance Metrics must provide 10 measurements."
一旦 XCTestLog
方法也被重写,因此它不会断言,可以添加额外的 4 个值而无需任何抱怨。不幸的是,该视图仍然只显示 10 个结果。
但是它确实更新了迷你视图中的总时间 + 标准差值。
调配前
Swizzling 并添加 4 个值后
为了查看超过 10 个结果,可能需要调整 XCode 运行时以告诉 table 显示更多项目。
我通常会扩展标准差值以包含我接受的范围。
一个明显的解决方法是在您正在执行的测量块内执行该操作 5 次。 (您需要更改预计时间。)
measure {
for _ in [1...5] {
// ...
}
}
在最新的 Xcode (11.0+) 中,您不需要调配来更改迭代次数。使用以下 function:
func measure(options: XCTMeasureOptions, block: () -> Void)
这将允许您指定 XCTMeasureOptions
其中有 iterationCount
属性。
来自文档的有趣注释:
A performance test runs its block iterationCount+1
times, ignoring the first iteration and recording metrics for the remaining iterations. The test ignores the first iteration to reduce measurement variance associated with “warming up” caches and other first-run behavior.
默认情况下,Xcodes 性能测试是 运行 十次,我的结果是这十次测试的平均值。问题是每次 运行 平均结果都会有很大差异,所以我必须 运行 测试至少五次才能获得收敛结果。这既乏味又费时;有没有办法将 XCode 或单元测试本身配置为 运行 十次以上?
简答:不,目前没有暴露的接口允许一个measure block超过十次。
较长的答案:不,但是有一个接口公开来修改度量块的某些指标。默认指标位于从 defaultPerformanceMetrics
返回的字符串数组中。目前似乎只支持一种指标:XCTPerformanceMetric_WallClockTime
。这仅指定了一个性能指标,该指标记录调用性能测试的 startMeasuring()
和 stopMeasuring()
方法之间的时间(以秒为单位),而不是块 运行.[=15= 的次数]
XCTestCase 的 class 转储公开了此方法:
- (void)_recordValues:(id)arg1 forPerformanceMetricID:(id)arg2 name:(id)arg3 unitsOfMeasurement:(id)arg4 baselineName:(id)arg5 baselineAverage:(id)arg6 maxPercentRegression:(id)arg7 maxPercentRelativeStandardDeviation:(id)arg8 maxRegression:(id)arg9 maxStandardDeviation:(id)arg10 file:(id)arg11 line:(unsigned long long)arg12;
调配此方法时,第一个参数 (arg1) 具有 10 个持续时间:
["0.003544568",
"0.003456569",
"0.003198263",
"0.003257955",
"0.003508724",
"0.003454298",
"0.003461192",
"0.00423787",
"0.003359195",
"0.003335757"]
我在将其传递回原始实现之前在此列表的末尾添加了 4 个新值(1.0、2.0、3.0、4.0),但不幸的是观察到一个不同的 class,XCTestLog
, 有一个内部完整性检查被触发:
Assertion failure in +[XCTestLog _messageForTest:didMeasureValues:forPerformanceMetricID:name:unitsOfMeasurement:baselineName:baselineAverage:maxPercentRegression:maxPercentRelativeStandardDeviation:maxRegression:maxStandardDeviation:file:line:]
caught "NSInternalInconsistencyException", "Performance Metrics must provide 10 measurements."
一旦 XCTestLog
方法也被重写,因此它不会断言,可以添加额外的 4 个值而无需任何抱怨。不幸的是,该视图仍然只显示 10 个结果。
但是它确实更新了迷你视图中的总时间 + 标准差值。
调配前
Swizzling 并添加 4 个值后
为了查看超过 10 个结果,可能需要调整 XCode 运行时以告诉 table 显示更多项目。
我通常会扩展标准差值以包含我接受的范围。
一个明显的解决方法是在您正在执行的测量块内执行该操作 5 次。 (您需要更改预计时间。)
measure {
for _ in [1...5] {
// ...
}
}
在最新的 Xcode (11.0+) 中,您不需要调配来更改迭代次数。使用以下 function:
func measure(options: XCTMeasureOptions, block: () -> Void)
这将允许您指定 XCTMeasureOptions
其中有 iterationCount
属性。
来自文档的有趣注释:
A performance test runs its block
iterationCount+1
times, ignoring the first iteration and recording metrics for the remaining iterations. The test ignores the first iteration to reduce measurement variance associated with “warming up” caches and other first-run behavior.