最大的性能杀手之一是操场右侧的输出。现在我将向您展示如何最小化此输出。
请参阅最后的示例代码。
最佳性能
最高效的方法是将所有性能关键代码放在 Playground 的 Sources 文件夹内的 .swift 文件中。
注意:要使用Sources 文件夹中的函数、类、属性和方法,您必须将它们标记为public。如果你想继承一个类,它必须被标记为open。
性能好但代码难看
以下方法(我认为这不是官方/有意的)可用于禁用游乐场输出,但也会导致丑陋的代码。但是,它对于暂时禁用输出很有用。
有两种主要方法(和两个技巧)可以实现最小输出量(如果您找到更好的方法,请告诉我们):
-
在Void(或Void?)表达式周围使用括号,例如赋值(通常会导致无输出,另请参见3。)。
var x = 0 // output: 0
(x = 1) // NO output
(x = 2 * x - 1) // NO output
(x.negate()) // NO output
注意:在 Swift 中,赋值返回 Void,如果是 optional chaining,则返回 Void?。
var x: (Int, Int)? = nil
if (x?.0 = 0) != nil {
// assignment was successful (x!=0 and now x=(0, x.1))
} else {
// assignment was not successful (x==nil)
}
-
分别初始化和声明变量。
var x: Int // NO output
(x = 0) // NO output
-
如果 1. 不起作用,请在 () 上方或下方添加额外的 no-op(无操作)行。
这发生在单行闭包中(可能在其他一些上下文中),例如:(另请参见下面的代码)
[1, 4, 5, 6].mmap{
() // without this line the line below would yield to an output
($1 = $0 + 1)
} as [Int]
-
您也可以使用所有表达式的元组,然后将其分配给一个变量,而不是用括号括起来:
var a: Any // this may be a useful definition in this context
var x: Int
var y: Int
(a = (x = 0,
y = 1,
x = y + 1,
y = x*x))
但是这可能会导致压痕灾难...
哪里不行(我没发现如何删除输出;这个列表可能不完整):
-
returns 在函数和闭包中
-
Optional 变量的声明例如:var x: Int?
Sequence 上的新 map 方法示例
用法:见上文第 3 点。
Sequence.map的签名是
func map<T>(_ transform: (Self.Element) throws -> T) rethrows -> [T]
由于我还没有找到删除returns 输出的方法,因此可以使用带有inout 参数的闭包(通过赋值获取“返回”值)。一个可能的签名可能是:
func mmap<U>(_ transform: (Element, inout U?) -> ()) -> [U]
所以我们可以在inout 参数中传递nil,因为它是所有可能的U 的一个很好的默认值,而不会对U 施加约束,这可能需要实例生成器(例如:init() { ... })。
不幸的是,Swfit 很难推断出U,因此您需要通过显式类型注释来帮助编译器。此外,var newElement: U?确实在侧边栏中返回 nil。
现在我将使用Any 而不是U?:
extension Sequence {
// ATTENTION: this is not as performant as the normal `map`!
func mmap<U>(transform: (Element, inout Any) -> ()) -> [U] {
var result: [U]
(result = [U]())
for element in self {
var newElement: Any
(newElement = 0) // some placeholder element
(transform(element, &newElement))
// assume the inout element to be of type `U`
(result.append(newElement as! U))
}
return result // the ONLY output in this method
}
}
您的示例代码
使用 Swift 4
var count = 0
for i in 0..<1_000_000_000 {
(count += 1)
if count % 100_000 == 0 {
// print only every 100_000th loop iteration
print(count)
}
}
没有括号:每秒大约 10.000 次循环迭代
带括号:每秒大约 10.000.000 次循环迭代!!!