github.com/lulzWill/go-agent@v2.1.2+incompatible/internal_benchmark_test.go (about)

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