<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] ## 性能優化 ### 減少[]byte的分配 ``` slice = slice[:0] ``` 所有的類型的Reset方法,均使用此方式。例如類型URI、Args、ByteBuffer、Cookie、RequestHeader、ResponseHeader等。 如: ``` // 清空 URI func (u *URI) Reset() { u.pathOriginal = u.pathOriginal[:0] u.scheme = u.scheme[:0] u.path = u.path[:0] // .... } ``` ### 方法參數盡量用[]byte. 純寫場景可避免用bytes.Buffer ### make 初始化時,指定長度,可避免多次分配內存 `a := make([]int, 0, 10)` 在初始化`slice`時,若事先知道`capacity`的長度,可優化性能,避免多次內存分配 ### 手段(去接口、內聯) 注意:去接口不利于代碼的可擴展性,需謹慎 > [參考網站](https://colobu.com/2019/12/31/small-changes-big-improvement/) ``` type DryFruit interface { Name() string Price() uint64 Family() string Distribution() string Increase() } type Chestnut struct { name string count uint64 } // Name 名稱. func (c Chestnut) Name() string { return c.name } //具體實現 //... // Increase 數量加一 func (c *Chestnut) Increase() { c.count++ } // 性能差ad type OriginGift struct { mu sync.Mutex dryFruit DryFruit //繼承接口 } // 性能比 OriginGift 更好 type ImprovedGift struct { mu sync.Mutex dryFruit *Chestnut //繼承 具體實現 } ``` ### 利用cpu緩存 > [參看](https://pengrl.com/p/9125/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io) ``` type Foo struct { a uint64 //_ [8]uint64 b uint64 //_ [8]uint64 } func main() { t1 := time.Now() var group sync.WaitGroup group.Add(2) foo :=Foo{} go func() { for i := 0; i < 1000 * 1000; i++ { atomic.AddUint64(&foo.a, 1) } group.Done() }() go func() { for i := 0; i < 1000 * 1000; i++ { atomic.AddUint64(&foo.b, 1) } group.Done() }() group.Wait() since := time.Since(t1) fmt.Printf("%+v\n", since) } ``` 1. 不利用cpu cache : 36.0059ms 2. 利用cpu cache取消注釋 _ [8]uint64 : 6.0059ms **使用場景** * 適用于多個相鄰的變量頻繁被并發讀寫的場,缺點是padding增加了內存使用量開銷 ### 禁止沒有timeout I/O 永遠不要啟動一個沒有 timeout 的 IO 操作。多考慮: ``` SetDeadline SetReadDeadline SetWriteDeadline ``` ### 優先使用 strconv 而不是 fmt Bad ``` for i := 0; i < b.N; i++ { s := fmt.Sprint(rand.Int()) } //BenchmarkFmtSprint-4 143 ns/op 2 allocs/op ``` Good ``` for i := 0; i < b.N; i++ { s := strconv.Itoa(rand.Int()) } //BenchmarkStrconv-4 64.2 ns/op 1 allocs/op ``` ### 避免字符串到字節的轉換 Bad ``` for i := 0; i < b.N; i++ { w.Write([]byte("Hello world")) } //BenchmarkBad-4 50000000 22.2 ns/op ``` Good ``` data := []byte("Hello world") for i := 0; i < b.N; i++ { w.Write(data) } //BenchmarkGood-4 500000000 3.25 ns/op ``` ### 盡量初始化時指定 Map 容量 為 make() 提供 容量(hint) 信息嘗試在初始化時調整 map 大小, 這減少了在將元素添加到 map 時增長 map 和 分配(allocations) 的開銷 注意,map 不能保證分配 hint 個容量(hint) ,因此,即使提供了容量(hint),添加元素任然可以進行分配 Bad ``` m := make(map[string]os.FileInfo) files, _ := ioutil.ReadDir("./files") for _, f := range files { m[f.Name()] = f } ``` Good ``` files, _ := ioutil.ReadDir("./files") m := make(map[string]os.FileInfo, len(files)) for _, f := range files { m[f.Name()] = f } ``` ### 不要在文件操作循環中使用 defer bad 方式會導致系統的文件描述符耗盡,因為在所有文件都被處理之前,沒有文件會被關閉 bad ``` for _, filename := range filenames { f, err := os.Open(filename) if err != nil { return err } defer f.Close() // NOTE: risky; could run out of file descriptors // ...process f… } ``` good ``` for _, filename := range filenames { if err := doFile(filename); err != nil { return err } } func doFile(filename string) error { f, err := os.Open(filename) if err != nil { return err } defer f.Close() // ...process f… } ``` ### 使用 strings.Builder 構建字符串 在Go中,字符串是不可變的。這意味著每次創建字符串時,都將分配新的內存 使用 `strings.Builder`在內部實現,它寫入字節緩沖區。只有在生成器上調用String()時,才實際創建字符串,速度提高 近五倍 bad ``` a:="a" a+="b" fmt.Printf("%+v\n", a) ``` good ``` builder := strings.Builder{} builder.WriteString("a") builder.WriteString("b") fmt.Printf("%+v\n", builder.String()) ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看