github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/aggregator/client/writer_benchmark_test.go (about)

     1  // Copyright (c) 2018 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package client
    22  
    23  import (
    24  	"math/rand"
    25  	"testing"
    26  	"time"
    27  
    28  	"github.com/m3db/m3/src/metrics/encoding/protobuf"
    29  	"github.com/m3db/m3/src/metrics/metric"
    30  	"github.com/m3db/m3/src/metrics/metric/unaggregated"
    31  
    32  	"github.com/uber-go/tally"
    33  )
    34  
    35  var (
    36  	testLargerBatchTimer = unaggregated.MetricUnion{
    37  		Type:          metric.TimerType,
    38  		ID:            []byte("foo"),
    39  		BatchTimerVal: []float64{222.22, 345.67, 901.23345, 222.22, 345.67, 901.23345, 222.22, 345.67, 901.23345, 222.22, 345.67, 901.23345},
    40  	}
    41  )
    42  
    43  func BenchmarkParallelWriter(b *testing.B) {
    44  	numShards := 16
    45  	opts := NewOptions()
    46  	writer := &writer{
    47  		log:             opts.InstrumentOptions().Logger(),
    48  		metrics:         newWriterMetrics(tally.NoopScope),
    49  		encoderOpts:     opts.EncoderOptions(),
    50  		maxBatchSize:    opts.MaxBatchSize(),
    51  		queue:           testNoOpQueue{},
    52  		encodersByShard: make(map[uint32]*lockedEncoder),
    53  	}
    54  	writer.newLockedEncoderFn = newLockedEncoder
    55  
    56  	b.RunParallel(func(pb *testing.PB) {
    57  		s := rand.NewSource(time.Now().UnixNano())
    58  		r := rand.New(s)
    59  
    60  		for pb.Next() {
    61  			shard := r.Intn(numShards)
    62  			payload := payloadUnion{
    63  				payloadType: untimedType,
    64  				untimed: untimedPayload{
    65  					metric:    testLargerBatchTimer,
    66  					metadatas: testStagedMetadatas,
    67  				},
    68  			}
    69  			if err := writer.Write(uint32(shard), payload); err != nil {
    70  				b.Fatalf("failed to successfully write metric: %v", err)
    71  			}
    72  		}
    73  	})
    74  }
    75  
    76  func BenchmarkSerialOneShardWriter(b *testing.B) {
    77  	numShards := 1
    78  	opts := NewOptions()
    79  	writer := &writer{
    80  		log:             opts.InstrumentOptions().Logger(),
    81  		metrics:         newWriterMetrics(tally.NoopScope),
    82  		encoderOpts:     opts.EncoderOptions(),
    83  		maxBatchSize:    opts.MaxBatchSize(),
    84  		queue:           testNoOpQueue{},
    85  		encodersByShard: make(map[uint32]*lockedEncoder),
    86  	}
    87  	writer.newLockedEncoderFn = newLockedEncoder
    88  
    89  	b.RunParallel(func(pb *testing.PB) {
    90  		s := rand.NewSource(time.Now().UnixNano())
    91  		r := rand.New(s)
    92  
    93  		for pb.Next() {
    94  			shard := r.Intn(numShards)
    95  			payload := payloadUnion{
    96  				payloadType: untimedType,
    97  				untimed: untimedPayload{
    98  					metric:    testLargerBatchTimer,
    99  					metadatas: testStagedMetadatas,
   100  				},
   101  			}
   102  			if err := writer.Write(uint32(shard), payload); err != nil {
   103  				b.Fatalf("failed to successfully write metric: %v", err)
   104  			}
   105  		}
   106  	})
   107  }
   108  
   109  func BenchmarkSerialWriter(b *testing.B) {
   110  	numShards := 16
   111  	opts := NewOptions()
   112  	encoder := newLockedEncoder(opts.EncoderOptions())
   113  	w := &writer{
   114  		log:             opts.InstrumentOptions().Logger(),
   115  		metrics:         newWriterMetrics(tally.NoopScope),
   116  		encoderOpts:     opts.EncoderOptions(),
   117  		maxBatchSize:    opts.MaxBatchSize(),
   118  		queue:           testNoOpQueue{},
   119  		encodersByShard: make(map[uint32]*lockedEncoder),
   120  	}
   121  	w.newLockedEncoderFn = newLockedEncoder
   122  	writer := &testSerialWriter{
   123  		writer:  w,
   124  		encoder: encoder,
   125  	}
   126  
   127  	b.RunParallel(func(pb *testing.PB) {
   128  		s := rand.NewSource(time.Now().UnixNano())
   129  		r := rand.New(s)
   130  
   131  		for pb.Next() {
   132  			shard := r.Intn(numShards)
   133  			payload := payloadUnion{
   134  				payloadType: untimedType,
   135  				untimed: untimedPayload{
   136  					metric:    testLargerBatchTimer,
   137  					metadatas: testStagedMetadatas,
   138  				},
   139  			}
   140  			if err := writer.Write(uint32(shard), payload); err != nil {
   141  				b.Fatalf("failed to successfully write metric: %v", err)
   142  			}
   143  		}
   144  	})
   145  }
   146  
   147  type testNoOpQueue struct{}
   148  
   149  func (q testNoOpQueue) Enqueue(protobuf.Buffer) error { return nil }
   150  func (q testNoOpQueue) Close() error                  { return nil }
   151  func (q testNoOpQueue) Size() int                     { return 0 }
   152  func (q testNoOpQueue) Flush()                        {}
   153  
   154  type testSerialWriter struct {
   155  	*writer
   156  
   157  	encoder *lockedEncoder
   158  }
   159  
   160  func (mw *testSerialWriter) Write(
   161  	_ uint32,
   162  	payload payloadUnion,
   163  ) error {
   164  	return mw.encodeWithLock(mw.encoder, payload)
   165  }