Created
October 26, 2014 16:14
-
-
Save gdamore/08c731ff9e9e625b25f7 to your computer and use it in GitHub Desktop.
switch message cache to sync.Pool
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/message.go b/message.go | |
index 2ae59a5..e1321e8 100644 | |
--- a/message.go | |
+++ b/message.go | |
@@ -15,6 +15,7 @@ | |
package mangos | |
import ( | |
+ "sync" | |
"sync/atomic" | |
) | |
@@ -32,18 +33,26 @@ type Message struct { | |
refcnt int32 | |
} | |
-type msgCacheInfo struct { | |
- maxbody int | |
- cache chan *Message | |
+type msgPool struct { | |
+ msgSize int; | |
+ sync.Pool | |
+}; | |
+ | |
+func (p *msgPool) New() interface{} { | |
+ m := &Message{} | |
+ m.bbuf = make([]byte, 0, p.msgSize) | |
+ m.hbuf = make([]byte, 0, 32) | |
+ m.bsize = p.msgSize | |
+ return m | |
} | |
// We can tweak these! | |
-var messageCache = []msgCacheInfo{ | |
- {maxbody: 64, cache: make(chan *Message, 2048)}, // 128K | |
- {maxbody: 128, cache: make(chan *Message, 1024)}, // 128K | |
- {maxbody: 1024, cache: make(chan *Message, 1024)}, // 1 MB | |
- {maxbody: 8192, cache: make(chan *Message, 256)}, // 2 MB | |
- {maxbody: 65536, cache: make(chan *Message, 64)}, // 4 MB | |
+var messageCache = []*msgPool{ | |
+ {msgSize: 64}, | |
+ {msgSize: 128}, | |
+ {msgSize: 1024}, | |
+ {msgSize: 8192}, | |
+ {msgSize: 65536}, | |
} | |
// Free decrements the reference count on a message, and releases its | |
@@ -52,20 +61,14 @@ var messageCache = []msgCacheInfo{ | |
// be recycled without engaging GC. This can have rather substantial | |
// benefits for performance. | |
func (m *Message) Free() { | |
- var ch chan *Message | |
if v := atomic.AddInt32(&m.refcnt, -1); v > 0 { | |
return | |
} | |
for i := range messageCache { | |
- if m.bsize == messageCache[i].maxbody { | |
- ch = messageCache[i].cache | |
- break | |
+ if m.bsize == messageCache[i].msgSize { | |
+ messageCache[i].Put(m) | |
} | |
} | |
- select { | |
- case ch <- m: | |
- default: | |
- } | |
} | |
// Dup creates a "duplicate" message. What it really does is simply | |
@@ -84,23 +87,20 @@ func (m *Message) Dup() *Message { | |
// use of a "cache" which greatly reduces the load on the garbage collector. | |
func NewMessage(sz int) *Message { | |
var m *Message | |
- var ch chan *Message | |
for i := range messageCache { | |
- if sz < messageCache[i].maxbody { | |
- ch = messageCache[i].cache | |
- sz = messageCache[i].maxbody | |
+ if sz < messageCache[i].msgSize { | |
+ if v := messageCache[i].Get(); v != nil { | |
+ m = v.(*Message) | |
+ } | |
break | |
} | |
} | |
- select { | |
- case m = <-ch: | |
- default: | |
+ if m == nil { | |
m = &Message{} | |
m.bbuf = make([]byte, 0, sz) | |
m.hbuf = make([]byte, 0, 32) | |
m.bsize = sz | |
} | |
- | |
m.refcnt = 1 | |
m.Body = m.bbuf | |
m.Header = m.hbuf |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment