0

版本1:中OperationQueue較慢劃分任務比運行所有它一次

func longTask(for myData:Data){ 

    let tick = Date() // startTime 

    let fileDataLength = myData.count 
    let count = 0 

    while count < fileDataLength{ 

     //task 1 
     task1Result = task1() 

     //task 2 
     task2Result = task2(task1Result) 

     //task 3 
     task3 result = task3(task1Result) 

     count = count + incrementCount 

    } 
    NSLog("%f",tick.timeInterverSinceNow) // print out -0.06 
    } 

版本2:

func longTask(for myData: Data){ 

    let fileDataLength = myData.count 

    let count = 0 

    let testQueue = OperationQueue() 

    while count < fileDataLength{ 

     //task 1 
     task1Result = task1() 
     { 
      // store all needed value 
      let name:String = task1Result.mane 
      ... 
      testQueue.addOperation{ // do in other thread 

       //task 2 
       task2Result = task2(name:name , ...) 

      //task 3 
      task3 result = task3(....) 
      } 
     }() 
     count = count + incrementCount 

    } 
    testQueue.waitUntilAllOperationsAreFinished()   
    NSLog("%f",tick.timeInterverSinceNow) // print out -0.5 

} 

在第2版,我想象如果longTask由運行線程A,通過將任務2和3移動到線程B ,而循環將接下來執行task1()在線程A中,而線程B在運行task2()和task3()。這會減少執行時間,但版本2比版本1慢10倍左右。我在這裏錯過了什麼?

回答

0

您的策略似乎沒問題,但我們對您的真實代碼一無所知。在我自己的環境中嘗試這種在操場

import PlaygroundSupport 
PlaygroundPage.current.needsIndefiniteExecution = true 

import Foundation 

let q = OperationQueue() 
let start = Date() 
print("start at", start) 

let n = 4 
var gs = [Int]() 

for j in 0..<n { 
    gs.append(0) 

    //q.addOperation { 
     var s = 0 
     for i in 0..<1000 { 
      s += i 
     } 
     gs[j] = s 
     let t = Date() 
     OperationQueue.main.addOperation { 
      let pt = Date() 
      print(s, j, "calculated:", t.timeIntervalSince(start), "printed:", pt.timeIntervalSince(start)) 
     } 
    //} 
} 

q.waitUntilAllOperationsAreFinished() 
print(gs, "GRANT TOTALL:", gs.reduce(0, +), "finished in", Date().timeIntervalSince(start), "seconds\n") 

處理器名稱:Intel酷睿i5
處理器速度:2,6 GHz的
處理器數量:1
的核心總數:2
L2高速緩存(每核心):256 KB L3高速緩存:3 MB
內存:16 GB

它打印

start at 2017-04-24 11:47:03 +0000 
[499500, 499500, 499500, 499500] GRANT TOTALL: 1998000 finished in 0.327317953109741 seconds 

499500 0 calculated: 0.0641489624977112 printed: 0.419835984706879 
499500 1 calculated: 0.130355000495911 printed: 0.420383989810944 
499500 2 calculated: 0.230241000652313 printed: 0.420827984809875 
499500 3 calculated: 0.326637983322144 printed: 0.421335995197296 

但OperationQueue

幫助
import PlaygroundSupport 
PlaygroundPage.current.needsIndefiniteExecution = true 

import Foundation 

let q = OperationQueue() 
let start = Date() 
print("start at", start) 

let n = 4 
var gs = [Int]() 

for j in 0..<n { 
    gs.append(0) 

    q.addOperation { 
     var s = 0 
     for i in 0..<1000 { 
      s += i 
     } 
     gs[j] = s 
     let t = Date() 
     OperationQueue.main.addOperation { 
      let pt = Date() 
      print(s, j, "calculated:", t.timeIntervalSince(start), "printed:", pt.timeIntervalSince(start)) 
     } 
    } 
} 

q.waitUntilAllOperationsAreFinished() 
print(gs, "GRANT TOTALL:", gs.reduce(0, +), "finished in", Date().timeIntervalSince(start), "seconds\n") 

它打印

start at 2017-04-24 11:58:45 +0000 
[499500, 499500, 499500, 499500] GRANT TOTALL: 1998000 finished in 0.186473965644836 seconds 

499500 0 calculated: 0.0701659917831421 printed: 0.388468980789185 
499500 1 calculated: 0.131179988384247 printed: 0.389105975627899 
499500 2 calculated: 0.165158987045288 printed: 0.389568984508514 
499500 3 calculated: 0.18574994802475 printed: 0.389993965625763 

正如預期的那樣,在代碼運行更快

怎麼樣的GS陣列?線程安全嗎?沒有!!所以最後,我們需要添加一些同步,即使它似乎不是我們很簡單的例子,嘀......

import PlaygroundSupport 
PlaygroundPage.current.needsIndefiniteExecution = true 

import Foundation 

let q = OperationQueue() 
let start = Date() 
print("start at", start) 

let n = 4 
var gs = [Int]() 
let queue = DispatchQueue(label: "MyArrayQueue", attributes: .concurrent) 

for j in 0..<n { 
    queue.async(flags: .barrier) { 
     gs.append(0) 
    } 

    q.addOperation { 
     var s = 0 
     for i in 0..<1000 { 
      s += i 
     } 
     queue.async(flags: .barrier) { 
      gs[j] = s 
     } 

     let t = Date() 
     OperationQueue.main.addOperation { 
      let pt = Date() 
      print(s, j, "calculated:", t.timeIntervalSince(start), "printed:", pt.timeIntervalSince(start)) 
     } 
    } 
} 

q.waitUntilAllOperationsAreFinished() 
var mgs:[Int] = [] 
queue.sync { 
    mgs = gs 
} 
print(mgs, "GRANT TOTALL:", mgs.reduce(0, +), "finished in", Date().timeIntervalSince(start), "seconds\n") 

最終結果

start at 2017-04-24 14:38:12 +0000 
[499500, 499500, 499500, 499500] GRANT TOTALL: 1998000 finished in 0.164229989051819 seconds 

499500 0 calculated: 0.0660730004310608 printed: 0.324115991592407 
499500 1 calculated: 0.0995810031890869 printed: 0.324918031692505 
499500 2 calculated: 0.126493990421295 printed: 0.325313985347748 
499500 3 calculated: 0.162481009960175 printed: 0.32580304145813 
+0

感謝您的回覆。我想我知道這裏的問題。如果調用addOperation 1000次而不添加單個代碼,它仍然會消耗0.3秒(i5,8gb)。因此它總共加上0.3的運行時間 – dellos