From 0a415cf0d6a1eb1617bebe2f849a4a5d24452661 Mon Sep 17 00:00:00 2001 From: Nathan VanBenschoten Date: Thu, 12 Oct 2017 15:12:30 -0400 Subject: [PATCH] raft: dont allocate slice and sort on every commit --- raft/raft.go | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/raft/raft.go b/raft/raft.go index 0c8c96c3f..c18100e89 100644 --- a/raft/raft.go +++ b/raft/raft.go @@ -245,6 +245,7 @@ type raft struct { maxMsgSize uint64 prs map[uint64]*Progress learnerPrs map[uint64]*Progress + matchBuf uint64Slice state StateType @@ -563,13 +564,19 @@ func (r *raft) bcastHeartbeatWithCtx(ctx []byte) { // the commit index changed (in which case the caller should call // r.bcastAppend). func (r *raft) maybeCommit() bool { - // TODO(bmizerany): optimize.. Currently naive - mis := make(uint64Slice, 0, len(r.prs)) - for _, p := range r.prs { - mis = append(mis, p.Match) + // Preserving matchBuf across calls is an optimization + // used to avoid allocating a new slice on each call. + if cap(r.matchBuf) < len(r.prs) { + r.matchBuf = make(uint64Slice, len(r.prs)) } - sort.Sort(sort.Reverse(mis)) - mci := mis[r.quorum()-1] + mis := r.matchBuf[:len(r.prs)] + idx := 0 + for _, p := range r.prs { + mis[idx] = p.Match + idx++ + } + sort.Sort(mis) + mci := mis[len(mis)-r.quorum()] return r.raftLog.maybeCommit(mci, r.Term) }