2014-09-27 40 views
7

有没有办法提高游乐场的执行速度? 我想迭代许多周期,而不是等待10分钟。斯威夫特操场执行速度

例如:

import UIKit 

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

此代码将执行的时间太长了。但我想要得到快速的结果。

+0

也许一个优化编译器会将该代码减少到:var count = 1000000000。 – zaph 2014-09-27 09:35:37

+0

@Zaph试着将这段代码粘贴到操场上,你会明白我的意思。 – zakhej 2014-09-27 09:41:16

+1

为什么人们投票关闭?你不知道什么是操场吗? – zakhej 2014-09-27 09:43:00

回答

3

我感觉到你的痛苦,我正在打印2D功能到[Double],然后转换为UIImageView。其中一个步骤是迭代数百万像素,并且花了很长时间。

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

0

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

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

2

最大的性能杀手之一是在操场右侧的输出。现在我会告诉你如何最小化这个输出。

在最后查看您的示例代码。


最佳性能

最高效的方法是让所有的性能关键代码的.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 
    

    注:在斯威夫特的任务返回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)) 
    

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

它不起作用(我发现没有办法如何删除输出;该列表可能不完整):在功能

  1. return S和关闭
  2. Optional变量的声明,例如:var x: Int?

map方法对Sequence

一个例子

用法:参见上述第3点。

Sequence.map签名是

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

因为我还没有找到一种方法如何删除的return S中的输出可以使用一个封闭与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 
    } 
} 

你的示例代码

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