Multithreading 将任务划分到OperationQueue比一次运行所有任务慢

Multithreading 将任务划分到OperationQueue比一次运行所有任务慢,multithreading,concurrency,grand-central-dispatch,nsoperationqueue,Multithreading,Concurrency,Grand Central Dispatch,Nsoperationqueue,第1版: 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 tas

第1版:

 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
  }
func长任务(对于myData:Data){
让勾选=日期()//开始时间
让fileDataLength=myData.count
让计数=0
而count
第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

}
func长任务(对于myData:Data){
让fileDataLength=myData.count
让计数=0
让testQueue=OperationQueue()
而count

在版本2中,我设想如果longTask由线程A运行,则将任务2和3移动到线程B,而循环将在线程A中执行下一个任务1(),而线程B运行task2()和task3()。这将减少执行时间,但版本2比版本1慢大约10倍。我在这里遗漏了什么?

您的策略似乎还可以,但我们对您真正的代码一无所知。在你的操场上试试这个

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")
但是在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")
正如预期的那样,代码运行得更快

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

谢谢你的回复。我想我知道这里的问题。如果调用addOperation 1000次而不在内部添加一个代码,则仍会消耗0.3秒(i5,8gb)。所以它加上0.3的总运行时间
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
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