Perform simultaneous operations based on certain conditions in a fast

I need to perform a set of operations based on some conditions, such as fetching data from a database, which takes about 10 seconds per request (ConnectedDevices.getAllDetails () takes 10 to execute and return a result).

it might be like the question below is an optimized way to find the IP address of a device within the iphone range but in my case I need to perform operations in batches as shown below:

var isConditionTrue = false var numProcessed = 0 let dbQueue = dispatch_queue_create("dbQueue", DISPATCH_QUEUE_SERIAL) // case 1 for i in 1...10 { dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_UTILITY.value), 0)) { let eachDBValue = ConnectedDevices.getAllDetails(i) dispatch_async(dbQueue) { if !eachDBValue { numProcessed++ } } } } // case 2 for i in 11...20 { dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_UTILITY.value), 0)) { let eachDBValue = ConnectedDevices.getAllDetails(i) dispatch_async(dbQueue) { if !eachDBValue { numProcessed++ } } } } // case 3 for i in 21...30 { dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_UTILITY.value), 0)) { let eachDBValue = ConnectedDevices.getAllDetails(i) dispatch_async(dbQueue) { if !ieachDBValue { numProcessed++ } } } } // case 4 for i in 31...40 { dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_UTILITY.value), 0)) { let eachDBValue = ConnectedDevices.getAllDetails(i) dispatch_async(dbQueue) { if !eachDBValue { numProcessed++ } } } } 

So, if in case 1, if the result is false for from 1 to 10, then it should go to case 2. If the result is true for any instance .. it should not fulfill any case 2,3,4.

Similarly for case 2, if the result is false for from 1 to 10, then it must go to case 3, otherwise it must stop. All this I need to do based on the conditions.

+5
source share
1 answer

This is my decision

Fake ConnectedDevices Class

This is a fake class that I created to test your script. As you can see, the getAllDetails method simulates database access. It waits 10 seconds and then returns true only if the input parameter is 40 . Thus, we can test this code in the worst case, since all calls must be made.

 class ConnectedDevices { class func getAllDetails(i:Int) -> Bool { sleep(10) return i == 40 } } 

Class loader

This is a class that will interact with Grand Central Dispatch .

 class Loader { private var numProcessed = 0 private let dbQueue = dispatch_queue_create("dbQueue", DISPATCH_QUEUE_SERIAL) private let utilityQueue = dispatch_get_global_queue(QOS_CLASS_UTILITY, 0) func search(completion:(result:Int?)->()) { dispatch_async(utilityQueue) { for group in [1, 11, 21, 31] { if let indexFound = self.search10(group) { completion(result: indexFound) return } } completion(result: nil) } } private func search10(startingIndex:Int) -> Int? { var indexFound : Int? dispatch_apply(10, utilityQueue) { (delta) -> () in let found = ConnectedDevices.getAllDetails(startingIndex + delta) dispatch_sync(self.dbQueue) { self.numProcessed++ // this is increased anyway if found { indexFound = startingIndex + delta } } } return indexFound } } 

search10 (startingIndex: Int)

This synchronous method takes Int as a parameter and makes 10 simultaneous calls to ConnectedDevices.getAllDetails . Each call is made with the addition of startingIndex in delta ( delta goes from 0 to 9 ).

The result is synchronously placed in a synchronous queue, where numProcessed safely grows. If found true , then the win index ( startingIndex + delta ) is returned.

If found never becomes true , nil returned.

Search()

This is the asych method. This is a simple for loop where group variables are populated with 1 , then 11 , then 21 and finally 31 .

On every call to search10 . If it returns an Int value, the value is passed to completion , otherwise the loop continues.

If 4 cycles are executed without the value returned from search10 , then nil is passed to completion .

Using

 import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() debugPrintln("Begin: \(NSDate())") Loader().search { (result) -> () in debugPrintln(result) debugPrintln("End: \(NSDate())") } } } 

Test

For 40 consecutive calls to ConnectedDevices.getAllDetails(...) 40 * 10 = 400 seconds required.

In my iPhone Simulator without any optimization enabled this code requires 120 seconds .

Hope this is what you need.

PS

  • Note that I am increasing numProcessed if the current result is true .
  • I did not find the target isConditionTrue , so I deleted it.
+2
source

All Articles