                     Future<Int, Void>(value: 4)]
                 )
 
-                future.on(success: { _ in
-                    remaining -= 1
-                    if remaining == 0 {
-                        expecation.fulfill()
+                future.on(success: { _ in expecation.fulfill() })
+            }
+            wait()
+        }
+    }
+
+    func testZipArrayOf1000() {
+        measure {
+            let iterations = 10
+            let futuresPerIteration = 1000
+
+            let expecation = self.expectation()
+            expecation.expectedFulfillmentCount = iterations
+
+            let promises = Array(0..<iterations).map { _ in
+                Array(0..<futuresPerIteration).map { _ in
+                    Promise<Int, Never>()
+                }
+            }
+
+            DispatchQueue.concurrentPerform(iterations: iterations) { iteration in
+                let zip = Future.zip(promises[iteration].map { $0.future })
+                zip.on(success: { _ in
+                    expecation.fulfill()
+                })
+            }
+
+            DispatchQueue.global().async {
+                DispatchQueue.concurrentPerform(iterations: iterations) { iteration in
+                    for promise in promises[iteration] {
+                        promise.succeed(value: 1)
                     }
-                })
-            }
+                }
+            }
+
             wait()
         }
     }
 }
 
-class FutureOperatorsPerformanceTests: XCTestCase {
+class FutureMapPerformanceTests: XCTestCase {
+
     func testMap() {
         let futures = Array(0..<10000).map { _ in
             Future(value: 1)

                item.succeed(value: 1)
            }
        }

        wait() // wait so that next test aren't affecteds
    }

    func testAttachingCallbacksToResolvedFuture() {
        let futures = Array(0..<10000).map { _ in
            return Future(value: 1)
        }

        measure {
            for future in futures {
                future.on(success: { _ in })
            }
        }
    }

    // MARK: - Fulfilling From Multiple Threads

    func testResolveFromMultipleThreads() {
        let promises = Array(0..<10).map { _ in
            Array(0..<10000).map { _ in
                Promise<Int, Never>()

        }
    }
}

class FutureFlatMapPerformanceTests: XCTestCase {

    func testFlatMapPending() {
        let futures = Array(0..<10000).map { _ in
            Promise<Int, Never>().future
        }

        measure {
            for future in futures {
                let _ = future.flatMap {
                    Future(value: $0)
                }
            }
        }
    }

    func testFlatMapResolvedReturnWithValue() {
        let futures = Array(0..<10000).map { _ in
            Future(value: 1)
        }

        measure {
            for future in futures {
                let _ = future.flatMap {
                    Future(value: $0)
                }
            }
        }
    }

    func testFlatMapResolvedReturnPending() {
        let futures = Array(0..<10000).map { _ in
            Future(value: 1)
        }

        measure {
            for future in futures {
                let _ = future.flatMap { _ in
                    Promise<Int, Never>().future // pending
                }
            }
        }
    }
}

class FutureMiscPerformanceTests: XCTestCase {
    func testObserveOn() {
        let futures = Array(0..<10000).map { _ in
            Future(value: 1)
        }

        let queue = DispatchQueue(label: "testObserveOn")
        measure {
            for future in futures {
                let _ = future.observe(on: queue)
            }
        }
    }
}
