0

Version 1:in einer Aufgabe Divide OperationQueue ist langsamer als alle führen Sie es einmal

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 
    } 

Version 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 

} 

in Version 2, Ich stellte mir vor, wenn Longtask wird betrieben von Thread A, durch Verschieben von Aufgabe 2 und 3 zu Thread B während Schleife wird als nächstes tun task1() in Thread A während Thread B Task2() und Task3() ausgeführt. Dies reduziert die Ausführungszeit, aber Version 2 ist ungefähr 10 Mal langsamer als Version 1. Was habe ich hier vermisst?

Antwort

0

Ihre Strategie scheint in Ordnung zu sein, aber wir wissen nichts über Ihren echten Code. versuchen Sie dies in Ihrem Spielplatz

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") 

in meiner eigenen Umgebung

Prozessortyp: Intel Core i5
Prozessorgeschwindigkeit: 2,6 GHz
Anzahl der Prozessoren: 1
Gesamtzahl der Kerne: 2
L2 Cache (pro Core): 256 KB L3 Cache: 3 MB
Speicher: 16 GB

druckt

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 

aber mit Hilfe von 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") 

druckt

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 

Wie erwartet, wird der Code schneller

Was ist mit dem GS-Array? Ist es threadsicher? NEIN!! So schließlich brauchen wir eine Synchronisation hinzuzufügen, auch wenn es nicht in unserem sehr einfachen Beispiel ...

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") 

Endergebnisses

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

Dank für Ihre Antwort erforderlich scheint. Ich denke, ich kannte das Problem hier. wenn call addOperation 1000 mal ohne einen einzigen code reingibt, verbraucht es immer noch 0,3 sekunden (i5,8gb). So dass es plus 0,3 in der gesamten Laufzeit – dellos

Verwandte Themen