2014-09-27 73 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次循環迭代!