Art*_*kov 13 ios swift swift-playground
有没有办法提高游乐场的执行速度?我想迭代很多周期而不是等待10分钟.
例如:
import UIKit
var count = 0
for var i = 0; i < 1000000000; i++ {
count++
}
Run Code Online (Sandbox Code Playgroud)
这段代码执行的时间太长了.但我希望得到快速的结果.
最大的性能杀手之一是操场右侧的输出。现在我将向您展示如何最小化此输出。
请参阅最后的示例代码。
最高效的方法是将所有性能关键代码放在.swiftPlaygroundSources文件夹内的一个文件中。
注意:为了使用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
Run Code Online (Sandbox Code Playgroud)
注意:在 Swift 中,一个赋值返回Void,在可选链的情况下它是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)
}
Run Code Online (Sandbox Code Playgroud)分别初始化和声明变量。
var x: Int // NO output
(x = 0) // NO output
Run Code Online (Sandbox Code Playgroud)如果 1. 不起作用,请在 上方或下方添加额外的无操作(无操作)行()。
这发生在单行闭包中(可能在其他一些上下文中),例如:(另见下面的代码)
[1, 4, 5, 6].mmap{
() // without this line the line below would yield to an output
($1 = $0 + 1)
} as [Int]
Run Code Online (Sandbox Code Playgroud)您还可以使用所有表达式的元组,然后将其分配给变量:
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))
Run Code Online (Sandbox Code Playgroud)
然而,这可能会导致压痕灾难......
它不起作用的地方(我找不到如何删除输出的方法;此列表可能不完整):
returns 在函数和闭包中Optional变量声明,例如:var x: Int?map方法的例子Sequence用法:见上文第 3 点。
的签名Sequence.map是
func map<T>(_ transform: (Self.Element) throws -> T) rethrows -> [T]
Run Code Online (Sandbox Code Playgroud)
由于我还没有找到如何删除returns的输出的方法,因此可以使用带inout参数的闭包(通过赋值获取“返回”值)。一个可能的签名可能是:
func mmap<U>(_ transform: (Element, inout U?) -> ()) -> [U]
Run Code Online (Sandbox Code Playgroud)
所以我们可以通过nil在inout争论,因为它是一个很好的默认为每个可能的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
}
}
Run Code Online (Sandbox Code Playgroud)
使用 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)
}
}
Run Code Online (Sandbox Code Playgroud)
没有括号:每秒大约 10.000 次循环迭代
带括号:每秒大约 10.000.000 次循环迭代!!!
我感觉到你的痛苦,我正在玩打印 2D 函数[Double]然后转换为UIImageView. 其中一个步骤是迭代数百万个像素,并且花费了很长时间。
任何计算密集型、重复性或可能耗时的内容都应放在 Playground 的“Sources”文件夹中。这样,代码就会在您的 Playground 运行之前进行预编译。将该for循环的输出放入可以从 Playground 调用的公共函数中。这样你就不必一直坐在那里看着操场通过for循环的次数。