why mutex performance significantly under preasure while channel remains steady

1,844 views
Skip to first unread message

davy zhang

unread,
Feb 18, 2013, 2:15:38 AM2/18/13
to golan...@googlegroups.com

After change the times from 30000 to 300000, the mutex version performance bad  as BenchmarkSyncMutex 1594250000 ns/op

but at 30000 the mutex version report 0.01 ns/op just as channel

Is there anything wrong with my code ? the performance go straight down 

here is the code

package benchmark


import (

"sync"

"testing"

)


func th1(mu *sync.Mutex, data *int, w *sync.WaitGroup) {

mu.Lock()

*data += 1

mu.Unlock()

w.Done()

}


func BenchmarkSyncMutex(b *testing.B) {

times := 300000 //changed to 30000 will fix the performance problem

mu := new(sync.Mutex)

data := 1

w := new(sync.WaitGroup)

w.Add(times)

for i := 0; i < times; i++ {

go th1(mu, &data, w)

mu.Lock()

data -= 1

mu.Unlock()

}

w.Wait()

println(data)

}


func ch1(c chan int, data *int) {

*data += 1

c <- 1

}


func BenchmarkSyncChannel(b *testing.B) {

c := make(chan int, 100)

data := 1

var s int

times := 300000

for i := 0; i < times; i++ {

go ch1(c, &data)

s += <-c

data -= 1

if s >= times {

break

}

}

println(data)

}

Dave Cheney

unread,
Feb 18, 2013, 2:17:00 AM2/18/13
to davy zhang, golan...@googlegroups.com
Please use play.golang.org for publishing large blobs of code.
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

davy zhang

unread,
Feb 18, 2013, 2:19:28 AM2/18/13
to golan...@googlegroups.com, davy zhang
ok, here is the play.golang version

I am just afraid of no one going to click the url ;)

Dave Cheney

unread,
Feb 18, 2013, 2:21:58 AM2/18/13
to davy zhang, golan...@googlegroups.com
Your benchmark does not respect the value of b.N, this may explain why
your numbers do not make a lot of sense.

You are also starting 300,000 goroutines who will spin on the same
lock ... there is a reason why people use atomic operations for
counters. 300,000 goroutines will each consume a page of memory each,
at least, which may stress your operating systems' memory allocator.

Finally - what are you hoping to achieve here ? If you would like to
contribute some microbenchmarks to Go, have a look at the runtime
package, there are already some there.

Dave

Jan Mercl

unread,
Feb 18, 2013, 2:22:27 AM2/18/13
to davy zhang, golang-nuts
On Mon, Feb 18, 2013 at 8:15 AM, davy zhang <davy...@gmail.com> wrote:

You're ignoring b.N, doing complex setups w/o b.StopTimer. The result numbers are useless.

-j

davy zhang

unread,
Feb 18, 2013, 2:36:52 AM2/18/13
to golan...@googlegroups.com, davy zhang
Sorry guys, I did a quick test but forget the basic ideas of benchmark, my fault

here is the modified code

I got the result:

BenchmarkSyncMutex 1
1
1
1
  500000      8057 ns/op
BenchmarkSyncChannel 1
1
1
1
1
 5000000       385 ns/op

Can this result tell that channel is faster than mutex?

I am doing this test for my project but it seem both channel and mutex works just fine, I still wonder which way is faster to go

Dave Cheney

unread,
Feb 18, 2013, 2:41:08 AM2/18/13
to davy zhang, golan...@googlegroups.com, davy zhang
Please don't reinvent the wheel, the benchmarks you need are already in the runtime package. 

There are faster ways if making a counter than a mutex and a value. 
--

davy zhang

unread,
Feb 18, 2013, 2:46:54 AM2/18/13
to golan...@googlegroups.com, davy zhang
Ok, thanks for point out that. I used channels a lot but didn't noticed there still atomic package and mutex available. I'll take a look at them, and the test file too :D
Thanks
Reply all
Reply to author
Forward
0 new messages