diff --git a/model/websocket_message.go b/model/websocket_message.go index dfffbf190e..c92943ecb0 100644 --- a/model/websocket_message.go +++ b/model/websocket_message.go @@ -5,8 +5,8 @@ package model import ( "encoding/json" - "fmt" "io" + "strconv" ) const ( @@ -281,7 +281,7 @@ func (ev *WebSocketEvent) EventType() string { func (ev *WebSocketEvent) ToJSON() ([]byte, error) { if ev.precomputedJSON != nil { - return []byte(fmt.Sprintf(`{"event": %s, "data": %s, "broadcast": %s, "seq": %d}`, ev.precomputedJSON.Event, ev.precomputedJSON.Data, ev.precomputedJSON.Broadcast, ev.GetSequence())), nil + return ev.precomputedJSONBuf(), nil } return json.Marshal(webSocketEventJSON{ ev.event, @@ -294,9 +294,7 @@ func (ev *WebSocketEvent) ToJSON() ([]byte, error) { // Encode encodes the event to the given encoder. func (ev *WebSocketEvent) Encode(enc *json.Encoder) error { if ev.precomputedJSON != nil { - return enc.Encode(json.RawMessage( - fmt.Sprintf(`{"event": %s, "data": %s, "broadcast": %s, "seq": %d}`, ev.precomputedJSON.Event, ev.precomputedJSON.Data, ev.precomputedJSON.Broadcast, ev.sequence), - )) + return enc.Encode(json.RawMessage(ev.precomputedJSONBuf())) } return enc.Encode(webSocketEventJSON{ @@ -307,6 +305,20 @@ func (ev *WebSocketEvent) Encode(enc *json.Encoder) error { }) } +// We write optimal code here sacrificing readability for +// performance. +func (ev *WebSocketEvent) precomputedJSONBuf() []byte { + return []byte(`{"event": ` + + string(ev.precomputedJSON.Event) + + `, "data": ` + + string(ev.precomputedJSON.Data) + + `, "broadcast": ` + + string(ev.precomputedJSON.Broadcast) + + `, "seq": ` + + strconv.Itoa(int(ev.sequence)) + + `}`) +} + func WebSocketEventFromJSON(data io.Reader) (*WebSocketEvent, error) { var ev WebSocketEvent var o webSocketEventJSON diff --git a/model/websocket_message_test.go b/model/websocket_message_test.go index e8f9c17ecd..73cf5dbae3 100644 --- a/model/websocket_message_test.go +++ b/model/websocket_message_test.go @@ -5,6 +5,8 @@ package model import ( "bytes" + "encoding/json" + "io" "testing" "github.com/stretchr/testify/assert" @@ -235,3 +237,18 @@ func TestWebSocketEventDeepCopy(t *testing.T) { }) require.NotEqual(t, ev.data, evCopy.data) } + +var err error + +func BenchmarkEncodeJSON(b *testing.B) { + message := NewWebSocketEvent(WebsocketEventUserAdded, "", "channelID", "", nil, "") + message.Add("user_id", "userID") + message.Add("team_id", "teamID") + + ev := message.PrecomputeJSON() + + enc := json.NewEncoder(io.Discard) + for i := 0; i < b.N; i++ { + err = ev.Encode(enc) + } +}