英文:
Huge difference in requests per second between a route with html template and one without in Golang
问题
我有以下的Go应用程序:
package main
import (
"pat"
"log"
"net/http"
"html/template"
"runtime"
)
func main() {
runtime.GOMAXPROCS(2)
route := pat.New()
route.Get("/user/:name/profile", http.HandlerFunc(profile))
route.Get("/", http.HandlerFunc(front))
http.Handle("/", route)
http.Handle("/static/", http.StripPrefix("/static/",
http.FileServer(http.Dir("static"))))
log.Println("Listening on port 5000...")
http.ListenAndServe(":5000", nil)
}
func profile(response http.ResponseWriter, request *http.Request) {
// 捕获URL请求查询并将其存储在“params”变量中
params := request.URL.Query()
// 获取“name”URL参数
name := params.Get(":name")
response.Write([]byte("Hello " + name))
}
type Person struct {
Name string
Age string
}
var Templates *template.Template
const LayoutPath string = "templates/layout.html"
func front(response http.ResponseWriter, request *http.Request) {
user := Person{Name: "testuser", Age: "39"}
Templates = template.Must(template.ParseGlob("themes/*.html"))
Templates.ExecuteTemplate(response, "layout", user)
}
当你访问127.0.0.1:5000/user/yourname/profile
时,每秒获得16000个请求,而访问127.0.0.1:5000
(front)只有2800个请求每秒。
我在这里做错了什么?
"layout"模板如下所示:
{{define "layout"}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content=""><meta name="author" content="">
<link rel='stylesheet' href='/static/stylesheet.css/' />
</head>
<body>
{{template "body" .}}
</body>
{{end}}
以及"body"模板:
{{define "body"}}
<p>test body</p>
{{end}}
我还尝试过更改GOMAXPROCS,但没有任何区别,甚至更糟。
我之前使用Python完成的应用程序获得了更多的请求,我对Go的性能表现感到失望。我转向Go是为了性能和想要每秒获得8-10000个请求。
你能帮我找出问题出在哪里吗?我应该转向C/C++以获得更好的性能吗?
英文:
I have the following Go app:
package main
import (
"pat"
"log"
"net/http"
"html/template"
"runtime"
)
func main() {
runtime.GOMAXPROCS(2)
route := pat.New()
route.Get("/user/:name/profile", http.HandlerFunc(profile))
route.Get("/", http.HandlerFunc(front))
http.Handle("/", route)
http.Handle("/static/", http.StripPrefix("/static/",
http.FileServer(http.Dir("static"))))
log.Println("Listening on port 5000...")
http.ListenAndServe(":5000", nil)
}
func profile(response http.ResponseWriter, request *http.Request) {
// Catch url request query and store it in "params" var
params := request.URL.Query()
// Get "name" url param
name := params.Get(":name")
response.Write([]byte("Hello " + name))
}
type Person struct {
Name string
Age string
}
var Templates *template.Template
const LayoutPath string = "templates/layout.html"
func front(response http.ResponseWriter, request *http.Request) {
user := Person{Name: "testuser", Age: "39"}
Templates = template.Must(template.ParseGlob("themes/*.html"))
Templates.ExecuteTemplate(response, "layout", user)
}
When you visit 127.0.0.1:5000/user/yourname/profile
you get 16000 requests per second while visiting 127.0.0.1:5000
(front) only 2800 requests per second..
What am I doing wrong here?
the "layout" template is like this
{{define "layout"}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content=""><meta name="author" content="">
<link rel='stylesheet' href='/static/stylesheet.css/' />
</head>
<body>
{{template "body" .}}
</body>
{{end}}
and the "body"
{{define "body"}}
<p>test body</p>
{{end}}
I also tried changing GOMAXPROCS without any difference if not worse.
I was using Python and got far more requests with a full finished app and I'm disappointed that it outperforms Go like this.. the reason I switched to Go was for performance and because I wanted to get 8-10000 requests per second.
Can you help me where I'm doing it wrong? Should I switch to C/C++ for better performance?
答案1
得分: 6
每次都解析多个文件,测试结果并不相等,只解析一次模板会提供更好的性能。
type Person struct {
Name string
Age string
}
var tmpl = template.Must(template.ParseGlob("themes/*.html"))
const LayoutPath string = "templates/layout.html"
func front(response http.ResponseWriter, request *http.Request) {
user := Person{Name: "testuser", Age: "39"}
tmpl.ExecuteTemplate(response, "layout", user)
}
英文:
You are parsing multiple files every time, the tests are no where equivalent, parsing the template once will give you better performance.
type Person struct {
Name string
Age string
}
var tmpl = template.Must(template.ParseGlob("themes/*.html"))
const LayoutPath string = "templates/layout.html"
func front(response http.ResponseWriter, request *http.Request) {
user := Person{Name: "testuser", Age: "39"}
tmpl.ExecuteTemplate(response, "layout", user)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论