- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有两个函数:
extension Array where Element: Hashable {
func uniqueOrderly() -> [Element] {
let startTime = CFAbsoluteTimeGetCurrent()
var set = Set<Element>()
var array = [Element]()
for element in self {
if set.contains(element) {
continue
}
set.insert(element)
array.append(element)
}
let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
print("Time for uniqueOrderly: \(timeElapsed)")
return array
}
}
第二个:
public extension Sequence where Element: Equatable {
func unique() -> [Element] {
let startTime = CFAbsoluteTimeGetCurrent()
var unique: [Element] {
return reduce(into: []) {
unique, x in
if !unique.contains(x) {
unique.append(x)
}
}
}
let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
print("Time for unique: \(timeElapsed)")
return unique
}
}
我正在对数组进行函数执行时间测量。
即:
let arrayToFilter = [1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1,1,2,4,6,1,2,5,7,9,3,3,1]
实际的函数调用和结果是这样的:
arrayToFilter.unique() //Time for unique: 0.00012195110321044922
arrayToFilter.uniqueOrderly() Time for uniqueOrderly: 0.02329099178314209
但是当我改变调用函数的顺序时,我的 unique()
函数显示出可怕的时间测量结果。
arrayToFilter.uniqueOrderly() //Time for uniqueOrderly: 0.0013059377670288086
arrayToFilter.unique() //Time for unique: 8.940696716308594e-06
所以我的问题是为什么我会遇到这种情况,不同的函数调用顺序?此外,当我在 for 循环中运行这些测试时,测量结果大不相同。 (大约 +- 1 秒)
所有测量都是在 playground 和真实的 iOS 应用程序中使用发布build设置(在模拟器上)完成的。
测试规范:
Xcode 版本 10.1
swift 4.2
最佳答案
你的 unique()
实现在计算 unique
之前计算耗时. unique
是一个计算变量,在访问时进行计算。
你的 uniqueOrderly()
实现仍将比 unique()
慢对于像这样的相当短的列表,因为与几乎总是命中前几个元素的线性搜索相比,插入到集合中是昂贵的。
至于排序问题,这几乎可以肯定是您测试它的方式造成的。微观分析非常具有挑战性。我通过将每个放入自己的 .swift
来测试这些文件并以 swift -O <file>
运行.但是,如果我按照您的方式将它们放在同一个文件中,并修复 unique()
实际计时它的事件,然后运行时时间非常一致 swift -O <file>
:
Time for uniqueOrderly: 1.800060272216797e-05
[1, 2, 4, 6, 5, 7, 9, 3]
Time for unique: 2.0265579223632812e-06
[1, 2, 4, 6, 5, 7, 9, 3]
Time for unique: 2.002716064453125e-05
[1, 2, 4, 6, 5, 7, 9, 3]
Time for uniqueOrderly: 2.9802322387695312e-06
[1, 2, 4, 6, 5, 7, 9, 3]
经过更多测试后,我怀疑这些差异部分是内存分配(内存是从操作系统中分块获取的,因此第一个分配器比第二个分配器付出更大的代价)和 L1 缓存。如果您对两个不同的数组(指向内存缓存)进行排序,几乎所有差异都会消失。但是这个算法对数组的构成也非常敏感,因为它有很多重复项。
无论如何,这种微优化是没有意义的。你整天都在追鬼。很难在微小的数据 block 上对微小的代码片段进行性能测试,并以适用于实际使用的方式对其进行优化。至少,您需要更多、更大的数组并在许多不同类型的分布上进行测试(大量重复与极少重复)。您必须在 Playgrounds 之外进行测试,并且必须使用优化器。
关于ios - Swift 函数执行时间测量问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53543226/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!