sync.Pool比使用channel慢得多,那么我们为什么要使用sync.Pool呢?

时间:2018-06-14 07:01:11

标签: go synchronization benchmarking channel pool

我读过sync.Pool设计,但发现它是两个逻辑,为什么我们需要localPool来解决锁定竞争。我们可以使用chan实现一个。

使用频道比sync.pool快4倍!

除了游泳池可以清除对象,它有什么优势?

这是池实现和基准测试代码:

package client

import (
    "runtime"
    "sync"
    "testing"
)

type MPool chan interface{}


type A struct {
    s        string
    b        int
    overflow *[2]*[]*string 

}

var p = sync.Pool{
    New: func() interface{} { return new(A) },
}

var mp MPool = make(chan interface{}, 100)

func get() interface{} {
    select {
    case r := <-mp:
        return r
    default:
        return new(A)
    }
}

func put(a interface{}) {
    select {
    case mp <- a:
    default:
    }
    return
}

func pool() {
    a := p.Get()
    p.Put(a)
}


func init() {
    runtime.GOMAXPROCS(8)
}

func BenchmarkName(b *testing.B) {
    for i := 0; i < 20; i++ {
        p.Put(new(A))
    }
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        for i := 0; i < 100; i++ {
            go func() {
                p.Put(p.Get())
            }()
        }
    }
}

func BenchmarkNotPool(b *testing.B) {
    for i := 0; i < 20; i++ {
        put(new(A))
    }
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        for i := 0; i < 100; i++ {
            a := get()
            put(a)
        }
    }
}

1 个答案:

答案 0 :(得分:4)

您没有对相同的事情进行基准测试,因此您无法比较结果。

if (e.deltaY>0) { owl.trigger('next.owl', [5000]); } else { owl.trigger('prev.owl', [5000]); } 启动goroutines,这些goroutine有重要的被无意中听到,你甚至不等待那些goroutine完成,而BenchmarkName()只是获取并将一个对象放入池中的同一个goroutine。

如果你修改BenchmarkNotPool()来做同样的事情,那么基准测试结果实际上表明它是另一种方式:BenchmarkName()快3倍以上,这是真的,所以这是它的使用/优势。 / p>

sync.Pool

结果:

func BenchmarkName(b *testing.B) {
    for i := 0; i < 20; i++ {
        p.Put(new(A))
    }
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        for i := 0; i < 100; i++ {
            p.Put(p.Get())
        }
    }
}

另请参阅相关问题:How to implement Memory Pooling in Golang