Created
May 20, 2015 09:24
-
-
Save ifraixedes/056175e0cf312db88f0e to your computer and use it in GitHub Desktop.
Benchmark Go Responses vs Standard Handler
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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 file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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 | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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