Mutex: How expensive is it to take?
On M2-Pro Mac the overhead of taking Mutex is about 20-30 nanoseconds. That means you can take Mutex:
- About 40K times per 1-millisecond.
- About 40M times per 1-second.
GT-Sandbox-Snapshot: Time Taking Mutex VS Not taking Mutex
Code
package com.glassthought.sandbox
import kotlinx.coroutines.*
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlin.system.measureNanoTime
fun main() = runBlocking {
val iterations = 100_000_000
// Operation without mutex
var counterWithoutMutex = 0
val timeWithoutMutex = measureNanoTime {
repeat(iterations) {
counterWithoutMutex++
}
}
println("Counter without mutex: $counterWithoutMutex")
println("Time taken without mutex: $timeWithoutMutex ns")
// Operation with mutex
val mutex = Mutex()
var counterWithMutex = 0
val timeWithMutex = measureNanoTime {
repeat(iterations) {
mutex.withLock {
counterWithMutex++
}
}
}
println("Counter with mutex: $counterWithMutex")
println("Time taken with mutex: $timeWithMutex ns")
// Calculate overhead per mutex operation
val overheadPerOperation = (timeWithMutex - timeWithoutMutex) / iterations
println("Overhead of Mutex.withLock{} per operation: $overheadPerOperation ns")
// In relation to millisecond how many times can we take mutex in one millisecond
// There are 1000 microseconds in one millisecond
// There are 1,000,000 nanoseconds in one millisecond
val timesPerMillisecond = 1_000_000 / overheadPerOperation
println("In relation to millisecond how many times can we take mutex in one millisecond: $timesPerMillisecond")
}
Command to reproduce:
gt.sandbox.checkout.commit ef2e717a8bc9b3ebb7cd \
&& cd "${GT_SANDBOX_REPO}" \
&& cmd.run.announce "./gradlew run --quiet"
Recorded output of command:
Counter without mutex: 100000000
Time taken without mutex: 5828000 ns
Counter with mutex: 100000000
Time taken with mutex: 2240589458 ns
Overhead of Mutex.withLock{} per operation: 22 ns
In relation to millisecond how many times can we take mutex in one millisecond: 45454
Backlinks