Pure Swift/C library that provides Go's concurrency features in Swift 2 (Linux ready)

SwiftGo is a pure Swift/C library that allows you to use Go's concurrency features in Swift 2.


https://github.com/Zewo/SwiftGo

Accepted Reply

Released version 0.2!

Replies

Way to go! : D

thanks mate!!

Released version 0.2!

Very cool project,


Just to know: You have some benchmark of this implementation compared to traditional way? (GCD for example).


Will be good know the "cost" of all this abstraction. I saw the examples and some of them are very useful.

What is the advantage in using these instead of simply gcd?

SwiftGo is faster than GCD because it creates lightweight coroutines instead of system threads which call to the OS. I created performance tests which I'll commit to the repo later. Here's what I got in my machine.


Test:


import XCTest
import SwiftGo
class PerformanceTests: XCTestCase {

    func testCoroutinePerformanceSwiftGo() {
        self.measureMetrics(XCTestCase.defaultPerformanceMetrics(), automaticallyStartMeasuring: false) {
            let channel = Channel<Void>()
            self.startMeasuring()
            go {
                self.stopMeasuring()
                channel <- Void()
            }
            <-channel
        }
    }

    func testThreadPerformanceGCD() {
        self.measureMetrics(XCTestCase.defaultPerformanceMetrics(), automaticallyStartMeasuring: false) {
            let semaphore = dispatch_semaphore_create(0)
            let queue =  dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)
            self.startMeasuring()
            dispatch_async(queue) {
                self.stopMeasuring()
                dispatch_semaphore_signal(semaphore)
            }
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
        }
    }

    func testSyncPerformanceSwiftGo() {
        self.measureBlock {
            let channel = Channel<Void>()
            go {
                channel <- Void()
            }
            <-channel
        }
    }

    func testSyncPerformanceGCD() {
        self.measureBlock {
            let semaphore = dispatch_semaphore_create(0)
            let queue =  dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)
            dispatch_async(queue) {
                dispatch_semaphore_signal(semaphore)
            }
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
        }
    }

}


Output:


Test Suite 'All tests' started at 2015-10-07 09:13:52.670
Test Suite 'SwiftGo Tests.xctest' started at 2015-10-07 09:13:52.671
Test Suite 'SwiftGo_Tests' started at 2015-10-07 09:13:52.671
Test Case '-[SwiftGo_Tests.SwiftGo_Tests testCoroutinePerformanceSwiftGo]' started.
/Users/paulo/Development/SwiftGo/SwiftGo Tests/SwiftGo_Tests.swift:23: Test Case '-[SwiftGo_Tests.SwiftGo_Tests testCoroutinePerformanceSwiftGo]' measured [Time, seconds] average: 0.000, relative standard deviation: 201.186%, values: [0.000038, 0.000003, 0.000002, 0.000002, 0.000002, 0.000002, 0.000002, 0.000002, 0.000002, 0.000002], performanceMetricID:com.apple.XCTPerformanceMetric_WallClockTime, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.100, maxStandardDeviation: 0.100
Test Case '-[SwiftGo_Tests.SwiftGo_Tests testCoroutinePerformanceSwiftGo]' passed (0.363 seconds).
Test Case '-[SwiftGo_Tests.SwiftGo_Tests testSyncPerformanceGCD]' started.
/Users/paulo/Development/SwiftGo/SwiftGo Tests/SwiftGo_Tests.swift:57: Test Case '-[SwiftGo_Tests.SwiftGo_Tests testSyncPerformanceGCD]' measured [Time, seconds] average: 0.003, relative standard deviation: 298.147%, values: [0.028991, 0.000038, 0.000028, 0.000008, 0.000014, 0.000018, 0.000014, 0.000005, 0.000018, 0.000020], performanceMetricID:com.apple.XCTPerformanceMetric_WallClockTime, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.100, maxStandardDeviation: 0.100
Test Case '-[SwiftGo_Tests.SwiftGo_Tests testSyncPerformanceGCD]' passed (0.281 seconds).
Test Case '-[SwiftGo_Tests.SwiftGo_Tests testSyncPerformanceSwiftGo]' started.
/Users/paulo/Development/SwiftGo/SwiftGo Tests/SwiftGo_Tests.swift:46: Test Case '-[SwiftGo_Tests.SwiftGo_Tests testSyncPerformanceSwiftGo]' measured [Time, seconds] average: 0.000, relative standard deviation: 50.890%, values: [0.000027, 0.000013, 0.000009, 0.000009, 0.000008, 0.000008, 0.000008, 0.000008, 0.000010, 0.000009], performanceMetricID:com.apple.XCTPerformanceMetric_WallClockTime, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.100, maxStandardDeviation: 0.100
Test Case '-[SwiftGo_Tests.SwiftGo_Tests testSyncPerformanceSwiftGo]' passed (0.254 seconds).
Test Case '-[SwiftGo_Tests.SwiftGo_Tests testThreadPerformanceGCD]' started.
/Users/paulo/Development/SwiftGo/SwiftGo Tests/SwiftGo_Tests.swift:36: Test Case '-[SwiftGo_Tests.SwiftGo_Tests testThreadPerformanceGCD]' measured [Time, seconds] average: 0.000, relative standard deviation: 25.810%, values: [0.000014, 0.000008, 0.000007, 0.000007, 0.000007, 0.000007, 0.000007, 0.000007, 0.000007, 0.000007], performanceMetricID:com.apple.XCTPerformanceMetric_WallClockTime, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.100, maxStandardDeviation: 0.100
Test Case '-[SwiftGo_Tests.SwiftGo_Tests testThreadPerformanceGCD]' passed (0.255 seconds).
Test Suite 'SwiftGo_Tests' passed at 2015-10-07 09:13:53.826.
  Executed 4 tests, with 0 failures (0 unexpected) in 1.153 (1.154) seconds
Test Suite 'SwiftGo Tests.xctest' passed at 2015-10-07 09:13:53.826.
  Executed 4 tests, with 0 failures (0 unexpected) in 1.153 (1.155) seconds
Test Suite 'All tests' passed at 2015-10-07 09:13:53.827.
  Executed 4 tests, with 0 failures (0 unexpected) in 1.153 (1.157) seconds
Program ended with exit code: 0


SwiftGo coroutine creation times: [0.000038, 0.000003, 0.000002, 0.000002, 0.000002, 0.000002, 0.000002, 0.000002, 0.000002, 0.000002]

GCD thread creation times: [0.000014, 0.000008, 0.000007, 0.000007, 0.000007, 0.000007, 0.000007, 0.000007, 0.000007, 0.000007]


SwiftGo sync times: [0.000027, 0.000013, 0.000009, 0.000009, 0.000008, 0.000008, 0.000008, 0.000008, 0.000010, 0.000009]

GCD sync times: [0.028991, 0.000038, 0.000028, 0.000008, 0.000014, 0.000018, 0.000014, 0.000005, 0.000018, 0.000020]

I ran the tests in release configuration, and seemed to me clearly optimized by the compiler .: 0.000001, 0.000001 ...... etc. You are not measure anything useful.


Just put some dummy "foo" call inside of each test produces:

SwiftGo Coroutine: [0.001315, 0.000011, 0.000004, 0.000004, 0.000004, 0.000004, 0.000004, 0.000004, 0.000004, 0.000004]

GCD async: [0.000140, 0.000037, 0.000025, 0.000020, 0.000016, 0.000035, 0.000025, 0.000016, 0.000015, 0.000015]


SwiftGo: [0.000032, 0.000011, 0.000008, 0.000008, 0.000017, 0.000009, 0.000008, 0.000008, 0.000008, 0.000008]

GCD: [0.000042, 0.000025, 0.000025, 0.000011, 0.000010, 0.000009, 0.000009, 0.000009, 0.000009, 0.000009]


But also its not a good test anyway, like you can see, all calls are under optimization pressure.


When I have the time I will try to do some tests in a more realistic context. Anyway, like i said before, very cool project!

When you do the more realistic context tests let me know, man!