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 }