- Notifications
You must be signed in to change notification settings - Fork0
tommymcguiver/randomnumber
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
http://localhost:8080/random?start=10&end=633
curl -v 'localhost:8080/random?start=10&end=633'
go test -bench .go test -bench . -benchmemgo test -bench Benchmark_ServeHttp -benchmemgo test -bench Benchmark_ServeHttp -benchmem -cpuprofile prof.cpu | tee bench.0go test -bench Benchmark_ServeHttp -benchmem -memprofile prof.mem | tee bench.0benchcmp bench.0 bench.1
go tool pprof randomnumber.test prof.cpu
atomic.AddInt64(&requestCount, 1)func TestServer_HandleRandom_Parallel(t *testing.T) {var wg sync.WaitGroupvar testServer = httptest.NewServer(http.HandlerFunc(HandleRandom))for i := 0; i < 2; i++ {wg.Add(1)go func() {defer wg.Done()res, err := http.Get(testServer.URL + "/random?start=1&end=2000")if err != nil {t.Error(err)return}if res.StatusCode != 200 {t.Error("Status code invalid")return}}()}//Wait until donewg.Wait()}
Builder
var randomBuilder strings.Builderfunc (rn *RandomNumber) MarshalJSON() ([]byte, error) {randomBuilder.Reset()fmt.Fprintf(&randomBuilder, `{"Number":%d}`, rn.Number)return []byte(randomBuilder.String()), nil}
bytes.Buffer
func (rn *RandomNumber) MarshalJSON() ([]byte, error) {buffer := bytes.NewBufferString(`{"Number":`)buffer.WriteString("1}")return buffer.Bytes(), nil}
Extra Alloc
fmt.Fprintf(w, "%s", string(b))
Global RNG
var rng = rand.New(mt19937.New())
Query Mapping
for k, v := range map[string][]string(r.URL.Query()) {switch k {case "start":if len(v) == 1 {start, err = strconv.Atoi(v[0])}if err != nil {w.WriteHeader(http.StatusBadRequest)return}case "end":if len(v) == 1 {end, err = strconv.Atoi(v[0])}if err != nil {w.WriteHeader(http.StatusBadRequest)return}}}
Sync Pool
Is ugly, but for maximum performance ( i.e. 0 allocations at runtime) you can do this.
var randomPool = sync.Pool{New: func() interface{} {return new(RandomNumber)},}var rng = rand.New(mt19937.New())func NewRandomNumber() *RandomNumber {rn := randomPool.Get().(*RandomNumber)defer randomPool.Put(rn)rn.Number = 0rng.Seed(time.Now().UnixNano())rn.Number = rng.Int63()return rn}
Contention
func reset(rw *httptest.ResponseRecorder) {m := rw.HeaderMapfor k := range m {delete(m, k)}body := rw.Bodybody.Reset()*rw = httptest.ResponseRecorder{Body: body,HeaderMap: m,}}func BenchmarkHealthParallel(b *testing.B) {r := httptest.NewRequest("GET", "http://example.com/health", nil)b.RunParallel(func(pb *testing.PB) {rw := httptest.NewRecorder()for pb.Next() {HandleHealth(rw, r)reset(rw)}})}
http://localhost:8080/debug/pprof/
import _ "net/http/pprof"....server := http.DefaultServeMuxserver.HandleFunc("/health", HandleHealth)server.HandleFunc("/random", HandleRandom)log.Println("Starting server...")log.Fatal(http.ListenAndServe(":8080", server))
About
Repository linked to my go profiling talk at BNE Gophers
Resources
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Releases
No releases published
Packages0
No packages published
Uh oh!
There was an error while loading.Please reload this page.