快速的游乐场执行速度

时间:2014-09-27 09:23:25

标签: ios swift swift-playground

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

例如:

import UIKit

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

此代码执行时间过长。但我希望得到快速的结果。

4 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:3)

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

最后查看示例代码。

最佳表现

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

注意:要使用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,如果是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)
    }
    
  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))
    

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

  5. 无效的地方(我发现无法删除输出;此列表可能不完整):

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

      上的新Sequence方法示例

      用法:见上文第3点。

      Sequence.map的签名是

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

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

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

      所以我们可以在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
          }
      }
      

      您的示例代码

      使用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循环迭代!!!

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

在 Xcode Playground 中加快构建速度并防止加载图标永远旋转:

  1. 转到右侧边栏,然后在 Playground Settings 中将 iOS 更改为 macOS
  2. 不是导入 UIKit,而是导入 Foundation (如果您不想使用 UIKit 框架中的特定内容,这将起作用)