From f75ca5badb68a7fe43689216e0c83875e6ef8ec5 Mon Sep 17 00:00:00 2001 From: xtaci Date: Thu, 8 Sep 2016 12:39:57 +0800 Subject: [PATCH] optimize stream.Write --- session.go | 10 ++++------ stream.go | 18 +++++++++++++----- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/session.go b/session.go index 76cf5b3..3d43a46 100644 --- a/session.go +++ b/session.go @@ -195,12 +195,10 @@ func (s *Session) recvLoop() { if _, ok := s.streams[f.sid]; !ok { stream := newStream(f.sid, s.config.MaxFrameSize, s) s.streams[f.sid] = stream - go func() { - select { - case s.chAccepts <- stream: - case <-s.die: - } - }() + select { + case s.chAccepts <- stream: + case <-s.die: + } } s.streamLock.Unlock() case cmdRST: diff --git a/stream.go b/stream.go index 6bb9b00..f8b1c93 100644 --- a/stream.go +++ b/stream.go @@ -2,6 +2,7 @@ package smux import ( "bytes" + "encoding/binary" "sync" "sync/atomic" @@ -70,14 +71,21 @@ func (s *Stream) Write(b []byte) (n int, err error) { } frames := s.split(b, cmdPSH, s.id) - // combine the frames - var buffer bytes.Buffer + // preallocate buffer + buffer := make([]byte, len(frames)*headerSize+len(b)) + bts := buffer + + // combine frames into a large blob for k := range frames { - bts, _ := frames[k].MarshalBinary() - buffer.Write(bts) + bts[0] = version + bts[1] = frames[k].cmd + binary.LittleEndian.PutUint16(bts[2:], uint16(len(frames[k].data))) + binary.LittleEndian.PutUint32(bts[4:], frames[k].sid) + copy(bts[headerSize:], frames[k].data) + bts = bts[len(frames[k].data)+headerSize:] } - if _, err = s.sess.writeBinary(buffer.Bytes()); err != nil { + if _, err = s.sess.writeBinary(buffer); err != nil { return 0, err } return len(b), nil