Skip to content

Instantly share code, notes, and snippets.

@toshi0383
Created November 14, 2019 12:15
Show Gist options
  • Save toshi0383/21d01dc9e9f23f979b360d1d75329fb2 to your computer and use it in GitHub Desktop.
Save toshi0383/21d01dc9e9f23f979b360d1d75329fb2 to your computer and use it in GitHub Desktop.
// comparing atomic operation performance
import Concurrency
import Foundation
final class Locking {
static let shared = Locking()
private(set) var isLocked: Bool = false
private let _lock = NSLock()
func lock() {
_lock.lock(); defer { _lock.unlock(); }
if isLocked { return }
isLocked = true
}
func unlock() {
_lock.lock(); defer { _lock.unlock(); }
isLocked = false
}
}
final class Atomic<A> {
private let queue = DispatchQueue(label: "Atomic serial queue")
private var _value: A
init(_ value: A) {
self._value = value
}
var value: A {
get {
return queue.sync { self._value }
}
}
func mutate(_ transform: (inout A) -> ()) {
queue.sync {
transform(&self._value)
}
}
}
extension Date {
var millisecondsSince1970:Int64 {
return Int64((self.timeIntervalSince1970 * 1000.0).rounded())
}
init(milliseconds:Int64) {
self = Date(timeIntervalSince1970: TimeInterval(milliseconds) / 1000)
}
}
func measure(_ f: () -> ()) {
let begin = Date().millisecondsSince1970
f()
let end = Date().millisecondsSince1970
print(end - begin)
}
let l = Locking.shared
let a = Atomic(false)
let uber = AtomicBool(initialValue: false)
let range = (0..<1000000)
measure {
range.forEach { _ in l.lock(); l.unlock() }
}
measure {
range.forEach { _ in a.mutate { $0 = true }; a.mutate { $0 = false } }
}
measure {
range.forEach { _ in
uber.compareAndSet(expect: false, newValue: true)
uber.compareAndSet(expect: true, newValue: false)
}
}
measure {
range.forEach { _ in
_ = uber.getAndSet(newValue: true)
_ = uber.getAndSet(newValue: false)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment