Skip to content

Instantly share code, notes, and snippets.

@gdamore
Created October 26, 2014 16:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gdamore/08c731ff9e9e625b25f7 to your computer and use it in GitHub Desktop.
Save gdamore/08c731ff9e9e625b25f7 to your computer and use it in GitHub Desktop.
switch message cache to sync.Pool
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