优化一个已有的 Go 程序 | 青训营

52 阅读1分钟

优化一个常见的Go web服务器程序:

go

Copy code

package main

import (
    "fmt"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello World!")
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

这是一个简单的HTTP服务器,对所有请求都返回"Hello World!"。

我们可以对它进行以下优化:

  1. 减少内存分配

handler函数中,每次请求都会执行fmt.Fprintf,这会导致一定的内存分配。我们可以将"Hello World!"定义为常量,直接写入response:

go

Copy code

const helloWorld = "Hello World!"

func handler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte(helloWorld))
}

这样可以消除内存分配。

  1. 重用连接

默认的HTTP服务会对每个请求建立并关闭连接。我们可以开启HTTP keep-alive功能,重用连接:

go

Copy code

server := &http.Server{
    Addr:         ":8080",
    IdleTimeout:  30 * time.Second,
    ReadTimeout:  5 * time.Second,
    WriteTimeout: 5 * time.Second,
}

server.ListenAndServe()

设置合理的超时时间可以重用连接提高性能。

  1. 利用多核

我们可以启动多个goroutine来监听服务,充分利用多核优势:

go

Copy code

func main() {
    for i := 0; i < 4; i++ {
        go func() {
            http.HandleFunc("/", handler)
            http.ListenAndServe(":8080", nil)
        }()
    }
}

启动多个goroutine监听同一端口。

通过上述优化,可以减少内存分配,重用连接提高并发,并利用多核优势。使这个简单的HTTP服务器性能大幅提升。

在优化Go程序时,正确使用profiling工具定位热点函数非常重要。照顾到内存分配、锁争用、GC压力都是优化思路。 通过这个例子,我能看到Go语言的优化潜力。千里之行始于足下,我会继续学习,争取能独立实现更复杂程序的优化。