github.com/newrelic/go-agent@v3.26.0+incompatible/internal_benchmark_test.go (about)

     1  // Copyright 2020 New Relic Corporation. All rights reserved.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package newrelic
     5  
     6  import (
     7  	"net/http"
     8  	"testing"
     9  )
    10  
    11  var (
    12  	sampleLicense = "0123456789012345678901234567890123456789"
    13  )
    14  
    15  // BenchmarkMuxWithoutNewRelic acts as a control against the other mux
    16  // benchmarks.
    17  func BenchmarkMuxWithoutNewRelic(b *testing.B) {
    18  	mux := http.NewServeMux()
    19  	mux.HandleFunc(helloPath, handler)
    20  
    21  	w := newCompatibleResponseRecorder()
    22  
    23  	b.ResetTimer()
    24  	b.ReportAllocs()
    25  
    26  	for i := 0; i < b.N; i++ {
    27  		mux.ServeHTTP(w, helloRequest)
    28  	}
    29  }
    30  
    31  // BenchmarkMuxWithNewRelic shows the approximate overhead of instrumenting a
    32  // request.  The numbers here are approximate since this is a test app: rather
    33  // than putting the transaction into a channel to be processed by another
    34  // goroutine, the transaction is merged directly into a harvest.
    35  func BenchmarkMuxWithNewRelic(b *testing.B) {
    36  	app := testApp(nil, nil, b)
    37  	mux := http.NewServeMux()
    38  	mux.HandleFunc(WrapHandleFunc(app, helloPath, handler))
    39  
    40  	w := newCompatibleResponseRecorder()
    41  
    42  	b.ResetTimer()
    43  	b.ReportAllocs()
    44  
    45  	for i := 0; i < b.N; i++ {
    46  		mux.ServeHTTP(w, helloRequest)
    47  	}
    48  }
    49  
    50  // BenchmarkMuxWithNewRelic shows the overhead of instrumenting a request when
    51  // the agent is disabled.
    52  func BenchmarkMuxDisabledMode(b *testing.B) {
    53  	cfg := NewConfig("my app", sampleLicense)
    54  	cfg.Enabled = false
    55  	app, err := newApp(cfg)
    56  	if nil != err {
    57  		b.Fatal(err)
    58  	}
    59  	mux := http.NewServeMux()
    60  	mux.HandleFunc(WrapHandleFunc(app, helloPath, handler))
    61  
    62  	w := newCompatibleResponseRecorder()
    63  
    64  	b.ResetTimer()
    65  	b.ReportAllocs()
    66  
    67  	for i := 0; i < b.N; i++ {
    68  		mux.ServeHTTP(w, helloRequest)
    69  	}
    70  }
    71  
    72  // BenchmarkTraceSegmentWithDefer shows the overhead of instrumenting a segment
    73  // using defer.  This and BenchmarkTraceSegmentNoDefer are extremely important:
    74  // Timing functions and blocks of code should have minimal cost.
    75  func BenchmarkTraceSegmentWithDefer(b *testing.B) {
    76  	cfg := NewConfig("my app", sampleLicense)
    77  	cfg.Enabled = false
    78  	app, err := newApp(cfg)
    79  	if nil != err {
    80  		b.Fatal(err)
    81  	}
    82  	txn := app.StartTransaction("my txn", nil, nil)
    83  	fn := func() {
    84  		defer StartSegment(txn, "alpha").End()
    85  	}
    86  	b.ResetTimer()
    87  	b.ReportAllocs()
    88  	for i := 0; i < b.N; i++ {
    89  		fn()
    90  	}
    91  }
    92  
    93  func BenchmarkTraceSegmentNoDefer(b *testing.B) {
    94  	cfg := NewConfig("my app", sampleLicense)
    95  	cfg.Enabled = false
    96  	app, err := newApp(cfg)
    97  	if nil != err {
    98  		b.Fatal(err)
    99  	}
   100  	txn := app.StartTransaction("my txn", nil, nil)
   101  	fn := func() {
   102  		s := StartSegment(txn, "alpha")
   103  		s.End()
   104  	}
   105  	b.ResetTimer()
   106  	b.ReportAllocs()
   107  	for i := 0; i < b.N; i++ {
   108  		fn()
   109  	}
   110  }
   111  
   112  func BenchmarkTraceSegmentZeroSegmentThreshold(b *testing.B) {
   113  	cfg := NewConfig("my app", sampleLicense)
   114  	cfg.Enabled = false
   115  	cfg.TransactionTracer.SegmentThreshold = 0
   116  	app, err := newApp(cfg)
   117  	if nil != err {
   118  		b.Fatal(err)
   119  	}
   120  	txn := app.StartTransaction("my txn", nil, nil)
   121  	fn := func() {
   122  		s := StartSegment(txn, "alpha")
   123  		s.End()
   124  	}
   125  	b.ResetTimer()
   126  	b.ReportAllocs()
   127  	for i := 0; i < b.N; i++ {
   128  		fn()
   129  	}
   130  }
   131  
   132  func BenchmarkDatastoreSegment(b *testing.B) {
   133  	cfg := NewConfig("my app", sampleLicense)
   134  	cfg.Enabled = false
   135  	app, err := newApp(cfg)
   136  	if nil != err {
   137  		b.Fatal(err)
   138  	}
   139  	txn := app.StartTransaction("my txn", nil, nil)
   140  	fn := func(txn Transaction) {
   141  		ds := DatastoreSegment{
   142  			StartTime:  txn.StartSegmentNow(),
   143  			Product:    DatastoreMySQL,
   144  			Collection: "my_table",
   145  			Operation:  "Select",
   146  		}
   147  		defer ds.End()
   148  	}
   149  	b.ResetTimer()
   150  	b.ReportAllocs()
   151  	for i := 0; i < b.N; i++ {
   152  		fn(txn)
   153  	}
   154  }
   155  
   156  func BenchmarkExternalSegment(b *testing.B) {
   157  	cfg := NewConfig("my app", sampleLicense)
   158  	cfg.Enabled = false
   159  	app, err := newApp(cfg)
   160  	if nil != err {
   161  		b.Fatal(err)
   162  	}
   163  	txn := app.StartTransaction("my txn", nil, nil)
   164  	fn := func(txn Transaction) {
   165  		es := &ExternalSegment{
   166  			StartTime: txn.StartSegmentNow(),
   167  			URL:       "http://example.com/",
   168  		}
   169  		defer es.End()
   170  	}
   171  	b.ResetTimer()
   172  	b.ReportAllocs()
   173  	for i := 0; i < b.N; i++ {
   174  		fn(txn)
   175  	}
   176  }
   177  
   178  func BenchmarkTxnWithSegment(b *testing.B) {
   179  	app := testApp(nil, nil, b)
   180  
   181  	b.ResetTimer()
   182  	b.ReportAllocs()
   183  
   184  	for i := 0; i < b.N; i++ {
   185  		txn := app.StartTransaction("my txn", nil, nil)
   186  		StartSegment(txn, "myFunction").End()
   187  		txn.End()
   188  	}
   189  }
   190  
   191  func BenchmarkTxnWithDatastore(b *testing.B) {
   192  	app := testApp(nil, nil, b)
   193  
   194  	b.ResetTimer()
   195  	b.ReportAllocs()
   196  
   197  	for i := 0; i < b.N; i++ {
   198  		txn := app.StartTransaction("my txn", nil, nil)
   199  		ds := &DatastoreSegment{
   200  			StartTime:  txn.StartSegmentNow(),
   201  			Product:    DatastoreMySQL,
   202  			Collection: "my_table",
   203  			Operation:  "Select",
   204  		}
   205  		ds.End()
   206  		txn.End()
   207  	}
   208  }
   209  
   210  func BenchmarkTxnWithExternal(b *testing.B) {
   211  	app := testApp(nil, nil, b)
   212  
   213  	b.ResetTimer()
   214  	b.ReportAllocs()
   215  
   216  	for i := 0; i < b.N; i++ {
   217  		txn := app.StartTransaction("my txn", nil, nil)
   218  		es := &ExternalSegment{
   219  			StartTime: txn.StartSegmentNow(),
   220  			URL:       "http://example.com",
   221  		}
   222  		es.End()
   223  		txn.End()
   224  	}
   225  }