繁体   English   中英

快速的游乐场执行速度

[英]Swift playground execution speed

有没有办法提高游乐场的执行速度? 我想迭代很多周期而不是等待10分钟。

例如:

import UIKit

var count = 0
for var i = 0; i < 1000000000; i++ {
    count++
}

这段代码执行的时间太长了。 但我希望得到快速的结果。

我感觉到你的痛苦,我正在玩2D打印功能到[Double]然后转换为UIImageView 其中一个步骤是迭代数百万个像素,这需要永远。

任何计算密集,重复或可能耗时的东西都应该放在操场的“Sources”文件夹中。 这样代码就会在你的游乐场运行之前进行预编译。 for循环的输出放在可以从操场上调用的公共函数中。 然后你不必坐在那里看着游乐场计数它经历了for循环。

最大的性能杀手之一是操场右侧的输出。 现在我将向您展示如何最小化此输出。

请参阅最后的示例代码。


最棒的表演

.swift方法是在操场中的Sources文件夹中的.swift文件中创建所有性能关键代码。

注意:要使用Sources文件夹中的函数,类,属性和方法,必须将它们标记为public 如果要将类子类化,则必须将其标记为open


良好的性能,但丑陋的代码

以下方法(我认为这不是官方/意图)可用于禁用操场输出,但也会导致丑陋的代码。 但是暂时禁用输出是有好处的。

实现最小输出量有两种主要方式(和两种技巧)( 如果您找到更好的方式让我们知道 ):

  1. Void (或Void? )表达式周围使用括号,如赋值(通常导致无输出,另请参见3.)。

     var x = 0 // output: 0 (x = 1) // NO output (x = 2 * x - 1) // NO output (x.negate()) // NO output 

    注意:在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) } 
  2. 分别初始化和声明变量。

     var x: Int // NO output (x = 0) // NO output 
  3. 如果1.不起作用,则在上方或下方添加额外的无操作(无操作)行()

    这种情况发生在单行闭包中(可能在其他一些上下文中),例如:(另见下面的代码)

     [1, 4, 5, 6].mmap{ () // without this line the line below would yield to an output ($1 = $0 + 1) } as [Int] 
  4. 您可以使用所有表达式的元组,然后将其分配给变量,而不是将每一行包装在括号中:

     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)) 

    然而,这可能导致压痕灾难......

哪里不起作用 (我找不到如何删除输出;这个列表可能不完整):

  1. 在函数和闭包中return s
  2. 声明Optional变量例如: var x: Int?

Sequence上新的map方法示例

用法:见上文第3点。

Sequence.map的签名是

func map<T>(_ transform: (Self.Element) throws -> T) rethrows -> [T]

由于我还没有找到如何删除return s输出的方法,因此可以使用带有inout参数的闭包(通过赋值获取“return”值)。 可能的签名可能是:

func mmap<U>(_ transform: (Element, inout U?) -> ()) -> [U]

所以我们可以把nilinout参数,因为它是为每个可能的一个很好的默认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循环迭代!!!

我遇到了这样的问题,经过几天的试验,我已经解决了这个问题。 我需要做的就是将所有代码移动到操场上的Sources文件夹中。 因此,之后执行速度得到提升。 我希望它对你有所帮助。

注意:不要忘记使用开放类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM