Created
November 14, 2019 12:16
-
-
Save toshi0383/728ae8c8b2f11693992e6bd189429f05 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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