https://kotlinlang.org logo
Title
e

Evgeniy Zaharov

11/17/2020, 12:47 PM
Hi. Does anybody know why mutex is much slowly compared to synchonization? In thread I will add small example:
val mutex = Mutex()
    var x: Int = 0

    @Test
    fun `performance check`() = runBlocking {
        val count = 100_000
        val threads = 2

        repeat(100_000) {
            x += 1
        }

        val s1 = measureTimeMillis {
            (1..threads).map {
                launch(<http://Dispatchers.IO|Dispatchers.IO>) {
                    repeat(count) {
                        testS()
                    }
                }
            }.forEach { it.join() }
        }

        val m1 = measureTimeMillis {
            (1..threads).map {
                launch(<http://Dispatchers.IO|Dispatchers.IO>) {
                    repeat(count) {
                        testM()
                    }
                }
            }.forEach { it.join() }
        }

        val s2 = measureTimeMillis {
            (1..threads).map {
                launch(<http://Dispatchers.IO|Dispatchers.IO>) {
                    repeat(count) {
                        testS()
                    }
                }
            }.forEach { it.join() }
        }

        val m2 = measureTimeMillis {
            (1..threads).map {
                launch(<http://Dispatchers.IO|Dispatchers.IO>) {
                    repeat(count) {
                        testM()
                    }
                }
            }.forEach { it.join() }
        }

        println("s1=$s1")
        println("m1=$m1")
        println("s2=$s2")
        println("m2=$m2")
    }

    private fun testS() = synchronized(mutex) {
        x += 1
    }

    private suspend fun testM() {
        mutex.withLock {
            x += 1
        }
    }
sN - synchronized test mN - mutex test with:
val count = 100_000
val threads = 2
will be
s1=48
m1=4019
s2=48
m2=2362
and with
val count = 100_000_000
val threads = 1
will be:
s1=2698
m1=2726
s2=2046
m2=4147
t

travis

11/17/2020, 3:00 PM
I've read that
Semaphore(1)
currently has better performance than
Mutex
, curious how it'd compare in your benchmarks.
e

Evgeniy Zaharov

11/17/2020, 3:25 PM
val count = 100_000 val threads = 5
synchronized1: 163
mutex1: 12243
semaphore1: 4988
synchronized2: 55
mutex2: 5103
semaphore2: 4429
and after small test rewrite:
synchronized1: 194
mutex1: 9041
semaphore1: 4479
synchronized2: 98
mutex2: 3661
semaphore2: 3520
with val count = 100_000_000 val threads = 1
synchronized1: 2111
mutex1: 3103
semaphore1: 1946
synchronized2: 2040
mutex2: 2883
semaphore2: 1925
but with an error of accuracy proportion is same, that
synchronized
is much faster for small action (like x+=1) for multiple threads. But for one thread Semaphore is really same as
synchronized
t

travis

11/17/2020, 3:45 PM
Thanks for sharing the benchmarks. Wish I could help you with understanding why there is a performance difference.