Skip to content

Commit

Permalink
perf(metarepos): add a pool for []*mrpb.Report
Browse files Browse the repository at this point in the history
This change adds the pool for []*mrpb.Report, which is reportQueuePool.

```
BenchmarkReportQueuePool/WithoutPool-16         	  763526	      1573 ns/op	    8192 B/op	       1 allocs/op
BenchmarkReportQueuePool/WithoutPool-16         	  745612	      1574 ns/op	    8192 B/op	       1 allocs/op
BenchmarkReportQueuePool/WithoutPool-16         	  738848	      1569 ns/op	    8192 B/op	       1 allocs/op
BenchmarkReportQueuePool/WithoutPool-16         	  765339	      1563 ns/op	    8192 B/op	       1 allocs/op
BenchmarkReportQueuePool/WithoutPool-16         	  739354	      1567 ns/op	    8192 B/op	       1 allocs/op
BenchmarkReportQueuePool/WithPool-16            	 4445330	       270.2 ns/op	      24 B/op	       1 allocs/op
BenchmarkReportQueuePool/WithPool-16            	 4342182	       271.9 ns/op	      24 B/op	       1 allocs/op
BenchmarkReportQueuePool/WithPool-16            	 4517366	       267.3 ns/op	      24 B/op	       1 allocs/op
BenchmarkReportQueuePool/WithPool-16            	 4440441	       263.5 ns/op	      24 B/op	       1 allocs/op
BenchmarkReportQueuePool/WithPool-16            	 4666981	       263.1 ns/op	      24 B/op	       1 allocs/op

```
  • Loading branch information
ijsong committed Jul 28, 2023
1 parent f6d9727 commit dd689cf
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 4 deletions.
7 changes: 3 additions & 4 deletions internal/metarepos/raft_metadata_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"syscall"
"time"

"github.com/gogo/status"
"go.etcd.io/etcd/pkg/fileutil"
"go.etcd.io/etcd/raft"
"go.etcd.io/etcd/raft/raftpb"
Expand All @@ -21,8 +22,6 @@ import (
"google.golang.org/grpc/health"
"google.golang.org/grpc/health/grpc_health_v1"

"github.com/gogo/status"

"github.com/kakao/varlog/internal/reportcommitter"
"github.com/kakao/varlog/pkg/types"
"github.com/kakao/varlog/pkg/util/container/set"
Expand Down Expand Up @@ -111,7 +110,7 @@ func NewRaftMetadataRepository(opts ...Option) *RaftMetadataRepository {
commitC: make(chan *committedEntry, 4096),
rnConfChangeC: make(chan raftpb.ConfChange, 1),
rnProposeC: make(chan []byte),
reportQueue: make([]*mrpb.Report, 0, 1024),
reportQueue: mrpb.NewReportQueue(),
runner: runner.New("mr", cfg.logger),
sw: stopwaiter.New(),
tmStub: tmStub,
Expand Down Expand Up @@ -351,7 +350,7 @@ func (mr *RaftMetadataRepository) processReport(ctx context.Context) {
if num > 0 {
reports = mrpb.NewReports(mr.nodeID, time.Now())
reports.Reports = mr.reportQueue
mr.reportQueue = make([]*mrpb.Report, 0, 1024)
mr.reportQueue = mrpb.NewReportQueue()
}
mr.muReportQueue.Unlock()

Expand Down
27 changes: 27 additions & 0 deletions proto/mrpb/raft_entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,34 @@ func NewReports(nodeID types.NodeID, ts time.Time) *Reports {

func (rs *Reports) Release() {
if rs != nil {
rq := (ReportQueue)(rs.Reports)
rq.Release()
*rs = Reports{}
reportsPool.Put(rs)
}
}

const (
reportQueueSize = 1024
)

type ReportQueue []*Report

var reportQueuePool = sync.Pool{
New: func() any {
q := make(ReportQueue, 0, reportQueueSize)
return &q
},
}

func NewReportQueue() ReportQueue {
rq := reportQueuePool.Get().(*ReportQueue)
return *rq
}

func (rq *ReportQueue) Release() {
if rq != nil {
*rq = (*rq)[0:0:reportQueueSize]
reportQueuePool.Put(rq)
}
}
84 changes: 84 additions & 0 deletions proto/mrpb/raft_entry_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package mrpb

import (
"math/rand"
"testing"
"time"

"github.com/stretchr/testify/require"

"github.com/kakao/varlog/pkg/types"
)

func TestReports(t *testing.T) {
const nid = types.NodeID(1)
rng := rand.New(rand.NewSource(time.Now().UnixNano()))

for i := 0; i < 1e4; i++ {
reports := NewReports(nid, time.Now())
require.Empty(t, reports.Reports)

queue := NewReportQueue()
require.Empty(t, queue)
require.Equal(t, reportQueueSize, cap(queue))
numReports := rng.Intn(reportQueueSize*2) + 1
for j := 0; j < numReports; j++ {
queue = append(queue, &Report{})
}
require.Len(t, queue, numReports)
reports.Reports = queue

reports.Release()
}
}

func TestReportQueuePool(t *testing.T) {
rng := rand.New(rand.NewSource(time.Now().UnixNano()))

for i := 0; i < 1e4; i++ {
queue := NewReportQueue()
require.Empty(t, queue)
require.Equal(t, reportQueueSize, cap(queue))

numReports := rng.Intn(reportQueueSize*2) + 1
for j := 0; j < numReports; j++ {
queue = append(queue, &Report{})
}
require.Len(t, queue, numReports)

queue.Release()
}
}

func BenchmarkReportQueuePool(b *testing.B) {
const numReports = 128
predefinedReports := make([]*Report, numReports)
for i := 0; i < numReports; i++ {
predefinedReports[i] = &Report{}
}
reports := &Reports{}

reports.Reports = make([]*Report, 0, reportQueueSize)
b.ResetTimer()
b.Run("WithoutPool", func(b *testing.B) {
for n := 0; n < b.N; n++ {
for j := 0; j < numReports; j++ {
reports.Reports = append(reports.Reports, predefinedReports[j])
}
reports.Reports = make([]*Report, 0, reportQueueSize)
}
})

reports.Reports = NewReportQueue()
b.ResetTimer()
b.Run("WithPool", func(b *testing.B) {
for n := 0; n < b.N; n++ {
for j := 0; j < numReports; j++ {
reports.Reports = append(reports.Reports, predefinedReports[j])
}
rq := (ReportQueue)(reports.Reports)
rq.Release()
reports.Reports = NewReportQueue()
}
})
}

0 comments on commit dd689cf

Please sign in to comment.