user3717756
user3717756

Reputation:

Huge difference in requests per second between a route with html template and one without in Golang

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?

Upvotes: 0

Views: 771

Answers (1)

OneOfOne
OneOfOne

Reputation: 99274

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

Upvotes: 6

Related Questions