import Foundation
@main
enum Test {
static func main () async {
testStateHolderLocked()
await testStateHolderActor()
await testStateHolderActor2()
}
}
// [https://forums.swift.org/t/i-was-playing-with-measuring-actor-performance/75005]
final class StateHolderLock {
var lock = os_unfair_lock_s()
init() {}
var sum = 0
var onNewValueReceived: ((Int) -> Void)!
func handleValueRecieved(_ val: Int) {
os_unfair_lock_lock(&lock)
sum += val
os_unfair_lock_unlock(&lock)
onNewValueReceived(val)
}
}
final actor StateHolderActor {
init() {}
var sum = 0
nonisolated(unsafe) var onNewValueReceived: ((Int) -> Void)!
func handleValueRecieved(_ val: Int) {
sum += val
onNewValueReceived(val)
}
}
let iterations = 1000000
func testStateHolderActor() async {
await measure ("Actor:") {
let actor = StateHolderActor()
var sum = 0
actor.onNewValueReceived = { val in
sum += val
}
for _ in 0 ..< iterations {
await actor.handleValueRecieved(1)
}
}
}
func testStateHolderLocked() {
measure ("Locked:") {
let actor = StateHolderLock()
var sum = 0
actor.onNewValueReceived = { val in
sum += val
}
for _ in 0 ..< iterations {
actor.handleValueRecieved(1)
}
}
}
// [https://forums.swift.org/t/i-was-playing-with-measuring-actor-performance/75005/2]
func testStateHolderActor2 () async {
await measure ("Actor2 :") {
let actor = StateHolderActor()
var sum = 0
actor.onNewValueReceived = { val in
sum += val
}
func run (actor: isolated StateHolderActor) async {
for _ in 0 ..< iterations {
actor.handleValueRecieved(1)
}
}
await run (actor: actor)
}
}
func measure (_ prefix: String, _ f: () -> Void) {
let d = ContinuousClock ().measure {
f ()
}
print (prefix, d)
}
func measure (_ prefix: String, _ f: () async -> Void) async {
let d = await ContinuousClock ().measure {
await f ()
}
print (prefix, d)
}
Guaranteeing an actor executes off the main thread