Skip to content

Instantly share code, notes, and snippets.

@toshi0383
Created November 14, 2019 12:16
Show Gist options
  • Save toshi0383/728ae8c8b2f11693992e6bd189429f05 to your computer and use it in GitHub Desktop.
Save toshi0383/728ae8c8b2f11693992e6bd189429f05 to your computer and use it in GitHub Desktop.
// comparing atomic operation performance
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