Skip to content

Instantly share code, notes, and snippets.

@ifraixedes
Created May 20, 2015 09:24
Show Gist options
  • Save ifraixedes/056175e0cf312db88f0e to your computer and use it in GitHub Desktop.
Save ifraixedes/056175e0cf312db88f0e to your computer and use it in GitHub Desktop.
Benchmark Go Responses vs Standard Handler
/*
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE Version 2, December 2004
(http://www.wtfpl.net/about/)
Copyright (C) 2015 Ivan Fraixedes (https://ivan.fraixed.es)
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
*/
package main
import (
"log"
"net/http"
"net/http/httptest"
"testing"
)
var req *http.Request
func init() {
var err error
req, err = http.NewRequest("GET", "http://localhost:9000", nil)
if err != nil {
log.Fatal(err)
}
}
func BenchmarkResponse(b *testing.B) {
h := Wrap(HelloBuddyResponse)
for i := 0; i < b.N; i++ {
w := httptest.NewRecorder()
h.ServeHTTP(w, req)
}
}
func BenchmarkStd(b *testing.B) {
for i := 0; i < b.N; i++ {
w := httptest.NewRecorder()
HelloBuddyStd.ServeHTTP(w, req)
}
}
/*
This code isn't released under any license, the most part of it has been created
by Karl Seguin in the code snippets embedded in a blog post under this URL
http://openmymind.net/Go-action-responses/
Author conserves his rights over it so he can request to take it down.
NOTE the codes may be slightly different from the original mentioned source and
it is released with NO WARRANTY
*/
package main
import "net/http"
var ServerErrorResponse = Respond(http.StatusInternalServerError, nil)
type Response interface {
WriteTo(out http.ResponseWriter)
}
// NormalResponse is a concrete implementation of Response which
// will suffice for most standard responses.
type NormalResponse struct {
status int
body []byte
header http.Header
}
// WriteTo writes the response to a standard http.ResponseWriter.
func (r *NormalResponse) WriteTo(out http.ResponseWriter) {
header := out.Header()
for k, v := range r.header {
header[k] = v
}
out.WriteHeader(r.status)
out.Write(r.body)
}
func (r *NormalResponse) Header(key, value string) *NormalResponse {
r.header.Set(key, value)
return r
}
// Respond creates a Normal response with the specified status
// and body.
func Respond(status int, body []byte) *NormalResponse {
return &NormalResponse{
body: body,
status: status,
header: make(http.Header),
}
}
// Wrap takes a func(*http.Request) and returns a standard HTTP handler
// func(http.ResponseWriter, *http.Request) which can be served by Go.
// This function is the glue that allows the simplified handlers to be used
// as standard handlers.
func Wrap(action func(req *http.Request) Response) http.Handler {
return http.HandlerFunc(func(out http.ResponseWriter, req *http.Request) {
res := action(req)
if res == nil {
res = ServerErrorResponse
}
res.WriteTo(out)
})
}
var responseCounter = 0
func HelloBuddyResponse(req *http.Request) Response {
responseCounter++
op := responseCounter % 2
switch op {
case 0:
return Respond(200, []byte(`<!DOCTYPE html>
<html>
<head><title>Hello</title></head>
<body><h1>Hello Buddy!</h1></body>
</html>
`)).Header("Content-Type", "text/html")
default:
return ServerErrorResponse
}
}
/*
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE Version 2, December 2004
(http://www.wtfpl.net/about/)
Copyright (C) 2015 Ivan Fraixedes (https://ivan.fraixed.es)
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
*/
package main
import "net/http"
var HelloBuddyStd http.Handler
func init() {
responseCounter := 0
HelloBuddyStd = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
responseCounter++
op := responseCounter % 2
switch op {
case 0:
w.WriteHeader(200)
header := w.Header()
header.Add("Content-Type", "text/html")
w.Write([]byte(
`<!DOCTYPE html>
<html>
<head><title>Hello</title></head>
<body><h1>Hello Buddy!</h1></body>
</html>`))
default:
w.WriteHeader(http.StatusInternalServerError)
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment