From 4306f7dd5d8bad4482fb4060403d6797e45d7136 Mon Sep 17 00:00:00 2001 From: john Date: Mon, 10 Sep 2018 18:00:40 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E8=BF=9Bgtype=E9=94=81=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/container/gtype/bytes.go | 39 ++++++++--------------- g/container/gtype/gtype_atomic_test.go | 44 ++++++++++++++++++++++++++ g/container/gtype/interface.go | 35 ++++++-------------- g/container/gtype/string.go | 36 ++++++--------------- 4 files changed, 75 insertions(+), 79 deletions(-) create mode 100644 g/container/gtype/gtype_atomic_test.go diff --git a/g/container/gtype/bytes.go b/g/container/gtype/bytes.go index 87cfeba18..93fae6807 100644 --- a/g/container/gtype/bytes.go +++ b/g/container/gtype/bytes.go @@ -7,18 +7,17 @@ package gtype import ( - "sync" + "sync/atomic" ) type Bytes struct { - mu sync.RWMutex - val []byte + val atomic.Value } func NewBytes(value...[]byte) *Bytes { t := &Bytes{} - if len(value) > 0 { - t.val = value[0] + if len(value) > 0 && value[0] != nil{ + t.val.Store(value[0]) } return t } @@ -28,28 +27,16 @@ func (t *Bytes) Clone() *Bytes { } func (t *Bytes) Set(value []byte) { - t.mu.Lock() - t.val = value - t.mu.Unlock() + if value == nil { + return + } + t.val.Store(value) } func (t *Bytes) Val() []byte { - t.mu.RLock() - b := t.val - t.mu.RUnlock() - return b + v := t.val.Load() + if v != nil { + return v.([]byte) + } + return nil } - -// 使用自定义方法执行加锁修改操作 -func (t *Bytes) LockFunc(f func(value []byte) []byte) { - t.mu.Lock() - t.val = f(t.val) - t.mu.Unlock() -} - -// 使用自定义方法执行加锁读取操作 -func (t *Bytes) RLockFunc(f func(value []byte)) { - t.mu.RLock() - f(t.val) - t.mu.RUnlock() -} \ No newline at end of file diff --git a/g/container/gtype/gtype_atomic_test.go b/g/container/gtype/gtype_atomic_test.go new file mode 100644 index 000000000..89d63e379 --- /dev/null +++ b/g/container/gtype/gtype_atomic_test.go @@ -0,0 +1,44 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://gitee.com/johng/gf. + +// go test *.go -bench=".*" + +package gtype + +import ( + "testing" + "sync/atomic" +) + +var ( + gt = New() + at = atomic.Value{} +) + + +func Benchmark_GtypeSet(b *testing.B) { + for i := 0; i < b.N; i++ { + gt.Set(i) + } +} + +func Benchmark_GtypeVal(b *testing.B) { + for i := 0; i < b.N; i++ { + gt.Val() + } +} + +func BenchmarkInt_AtomicStore(b *testing.B) { + for i := 0; i < b.N; i++ { + at.Store(i) + } +} + +func BenchmarkInt32_AtomicLoad(b *testing.B) { + for i := int32(0); i < int32(b.N); i++ { + at.Load() + } +} diff --git a/g/container/gtype/interface.go b/g/container/gtype/interface.go index 518a14a59..35ec814a4 100644 --- a/g/container/gtype/interface.go +++ b/g/container/gtype/interface.go @@ -7,19 +7,18 @@ package gtype import ( - "sync" + "sync/atomic" ) // 比较通用的并发安全数据类型 type Interface struct { - mu sync.RWMutex - val interface{} + val atomic.Value } func NewInterface(value...interface{}) *Interface { t := &Interface{} - if len(value) > 0 { - t.val = value[0] + if len(value) > 0 && value[0] != nil { + t.val.Store(value[0]) } return t } @@ -29,28 +28,12 @@ func (t *Interface) Clone() *Interface{ } func (t *Interface) Set(value interface{}) { - t.mu.Lock() - t.val = value - t.mu.Unlock() + if value == nil { + return + } + t.val.Store(value) } func (t *Interface) Val() interface{} { - t.mu.RLock() - b := t.val - t.mu.RUnlock() - return b -} - -// 使用自定义方法执行加锁修改操作 -func (t *Interface) LockFunc(f func(value interface{}) interface{}) { - t.mu.Lock() - defer t.mu.Unlock() - t.val = f(t.val) -} - -// 使用自定义方法执行加锁读取操作 -func (t *Interface) RLockFunc(f func(value interface{})) { - t.mu.RLock() - defer t.mu.RUnlock() - f(t.val) + return t.val.Load() } \ No newline at end of file diff --git a/g/container/gtype/string.go b/g/container/gtype/string.go index 2b4d15935..b3dfd33aa 100644 --- a/g/container/gtype/string.go +++ b/g/container/gtype/string.go @@ -7,18 +7,17 @@ package gtype import ( - "sync" + "sync/atomic" ) type String struct { - mu sync.RWMutex - val string + val atomic.Value } func NewString(value...string) *String { t := &String{} if len(value) > 0 { - t.val = value[0] + t.val.Store(value[0]) } return t } @@ -28,30 +27,13 @@ func (t *String) Clone() *String { } func (t *String) Set(value string) { - t.mu.Lock() - t.val = value - t.mu.Unlock() + t.val.Store(value) } func (t *String) Val() string { - t.mu.RLock() - s := t.val - t.mu.RUnlock() - return s + v := t.val.Load() + if v != nil { + return v.(string) + } + return "" } - -// 使用自定义方法执行加锁修改操作 -func (t *String) LockFunc(f func(value string) string) { - t.mu.Lock() - t.val = f(t.val) - t.mu.Unlock() -} - -// 使用自定义方法执行加锁读取操作 -func (t *String) RLockFunc(f func(value string)) { - t.mu.RLock() - f(t.val) - t.mu.RUnlock() -} - -