Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Repository linked to my go profiling talk at BNE Gophers

NotificationsYou must be signed in to change notification settings

tommymcguiver/randomnumber

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

http://localhost:8080/random?start=10&end=633

curl -v 'localhost:8080/random?start=10&end=633'

Go Test

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

Race Detection

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()}

Make JSON Encoding Faster

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}

Why is JSON encoding not faster when i prebuild a string?

Fixes

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 Profiling

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

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages


[8]ページ先頭

©2009-2025 Movatter.jp