簡體   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