Skip to content

Instantly share code, notes, and snippets.

@sbusso
Forked from alexedwards/_results
Created September 30, 2018 13:51
Show Gist options
  • Save sbusso/d1c0cafc88100d34303d0f3172a5d2b1 to your computer and use it in GitHub Desktop.
Save sbusso/d1c0cafc88100d34303d0f3172a5d2b1 to your computer and use it in GitHub Desktop.
SCS and Gorilla Sessions benchmarks
# SCS
BenchmarkSCSMemstore-8 200000 9573 ns/op 3643 B/op 49 allocs/op
BenchmarkSCSCookies-8 100000 23220 ns/op 7516 B/op 83 allocs/op
BenchmarkSCSRedis-8 30000 45783 ns/op 4459 B/op 76 allocs/op
BenchmarkSCSMySQL-8 300 5782698 ns/op 4382 B/op 73 allocs/op
BenchmarkSCSPostgres-8 500 3715685 ns/op 5585 B/op 96 allocs/op
# Gorilla
BenchmarkGorillaCookies-8 20000 63678 ns/op 16987 B/op 296 allocs/op
BenchmarkGorillaRedis-8 10000 109229 ns/op 17877 B/op 336 allocs/op
BenchmarkGorillaPostgres-8 300 5460733 ns/op 24498 B/op 485 allocs/op
# SCS (storing custom object)
BenchmarkSCSObjectMemstore-8 30000 47638 ns/op 12980 B/op 266 allocs/op
BenchmarkSCSObjectCookies-8 30000 60773 ns/op 17700 B/op 300 allocs/op
BenchmarkSCSObjectRedis-8 10000 104259 ns/op 13883 B/op 293 allocs/op
BenchmarkSCSObjectMySQL-8 300 5865694 ns/op 13800 B/op 290 allocs/op
BenchmarkSCSObjectPostgres-8 500 3926530 ns/op 15124 B/op 313 allocs/op
# Gorilla (storing custom object)
BenchmarkGorillaObjectCookies-8 20000 67899 ns/op 19302 B/op 320 allocs/op
BenchmarkGorillaObjectRedis-8 10000 123880 ns/op 18976 B/op 360 allocs/op
BenchmarkGorillaObjectPostgres-8 300 4073790 ns/op 26589 B/op 509 allocs/op
import (
"encoding/gob"
"net/http"
"net/http/httptest"
"os"
"testing"
"time"
redistore "gopkg.in/boj/redistore.v1"
"github.com/antonlindstrom/pgstore"
"github.com/garyburd/redigo/redis"
"github.com/gorilla/sessions"
)
func benchGorilla(b *testing.B, store sessions.Store) {
setupHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
s, err := store.Get(r, "session")
if err != nil {
b.Fatal(err)
}
s.Values["counter"] = 1
err = s.Save(r, w)
if err != nil {
b.Fatal(err)
}
})
benchHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
s, err := store.Get(r, "session")
if err != nil {
b.Fatal(err)
}
i, ok := s.Values["counter"].(int)
if ok == false {
b.Fatal(err)
}
s.Values["counter"] = i + 1
err = s.Save(r, w)
if err != nil {
b.Fatal(err)
}
})
w := httptest.NewRecorder()
r := new(http.Request)
setupHandler.ServeHTTP(w, r)
sessionCookie := w.Header().Get("Set-Cookie")
r = new(http.Request)
r.Header = make(http.Header)
r.Header.Add("Cookie", sessionCookie)
b.ResetTimer()
for n := 0; n < b.N; n++ {
var nr http.Request
nr = *r
benchHandler.ServeHTTP(w, &nr)
}
}
type User struct {
Name string
Age int
}
func benchGorillaObject(b *testing.B, store sessions.Store) {
gob.Register(new(User))
setupHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
s, err := store.Get(r, "session")
if err != nil {
b.Fatal(err)
}
s.Values["user"] = &User{"Alex", 33}
err = s.Save(r, w)
if err != nil {
b.Fatal(err)
}
})
benchHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
s, err := store.Get(r, "session")
if err != nil {
b.Fatal(err)
}
user, ok := s.Values["user"].(*User)
if ok == false {
b.Fatal(err)
}
user.Age = user.Age + 1
err = s.Save(r, w)
if err != nil {
b.Fatal(err)
}
})
w := httptest.NewRecorder()
r := new(http.Request)
setupHandler.ServeHTTP(w, r)
sessionCookie := w.Header().Get("Set-Cookie")
r = new(http.Request)
r.Header = make(http.Header)
r.Header.Add("Cookie", sessionCookie)
b.ResetTimer()
for n := 0; n < b.N; n++ {
var nr http.Request
nr = *r
benchHandler.ServeHTTP(w, &nr)
}
}
func BenchmarkGorillaCookies(b *testing.B) {
store := sessions.NewCookieStore(
[]byte("f71dc7e58abab014ddad2652475056f185164d262869c8931b239de52711ba87"),
[]byte("911182cec2f206986c8c82440adb7d17"),
)
benchGorilla(b, store)
}
func BenchmarkGorillaRedis(b *testing.B) {
pool := redis.NewPool(func() (redis.Conn, error) {
conn, err := redis.Dial("tcp", os.Getenv("SESSION_REDIS_TEST_ADDR"))
if err != nil {
return nil, err
}
return conn, err
}, 50)
defer pool.Close()
store, err := redistore.NewRediStoreWithPool(
pool,
[]byte("f71dc7e58abab014ddad2652475056f185164d262869c8931b239de52711ba87"),
)
if err != nil {
b.Fatal(err)
}
benchGorilla(b, store)
}
func BenchmarkGorillaPostgres(b *testing.B) {
store, err := pgstore.NewPGStore(
os.Getenv("SESSION_PG_TEST_DSN"),
[]byte("f71dc7e58abab014ddad2652475056f185164d262869c8931b239de52711ba87"),
)
if err != nil {
b.Fatal(err)
}
defer store.Close()
defer store.StopCleanup(store.Cleanup(time.Minute * 5))
benchGorilla(b, store)
}
func BenchmarkGorillaObjectCookies(b *testing.B) {
store := sessions.NewCookieStore(
[]byte("f71dc7e58abab014ddad2652475056f185164d262869c8931b239de52711ba87"),
[]byte("911182cec2f206986c8c82440adb7d17"),
)
benchGorillaObject(b, store)
}
func BenchmarkGorillaObjectRedis(b *testing.B) {
pool := redis.NewPool(func() (redis.Conn, error) {
conn, err := redis.Dial("tcp", os.Getenv("SESSION_REDIS_TEST_ADDR"))
if err != nil {
return nil, err
}
return conn, err
}, 50)
defer pool.Close()
store, err := redistore.NewRediStoreWithPool(
pool,
[]byte("f71dc7e58abab014ddad2652475056f185164d262869c8931b239de52711ba87"),
)
if err != nil {
b.Fatal(err)
}
benchGorillaObject(b, store)
}
func BenchmarkGorillaObjectPostgres(b *testing.B) {
store, err := pgstore.NewPGStore(
os.Getenv("SESSION_PG_TEST_DSN"),
[]byte("f71dc7e58abab014ddad2652475056f185164d262869c8931b239de52711ba87"),
)
if err != nil {
b.Fatal(err)
}
defer store.Close()
defer store.StopCleanup(store.Cleanup(time.Minute * 5))
benchGorillaObject(b, store)
}
package scs
import (
"database/sql"
"encoding/gob"
"net/http"
"net/http/httptest"
"os"
"testing"
"github.com/alexedwards/scs/engine/cookiestore"
"github.com/alexedwards/scs/engine/memstore"
"github.com/alexedwards/scs/engine/mysqlstore"
"github.com/alexedwards/scs/engine/pgstore"
"github.com/alexedwards/scs/engine/redisstore"
"github.com/alexedwards/scs/session"
"github.com/garyburd/redigo/redis"
)
func benchSCS(b *testing.B, engine session.Engine) {
manager := session.Manage(engine)
setupHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
err := session.PutInt(r, "counter", 1)
if err != nil {
b.Fatal(err)
}
})
benchHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
i, err := session.GetInt(r, "counter")
if err != nil {
b.Fatal(err)
}
err = session.PutInt(r, "counter", i+1)
if err != nil {
b.Fatal(err)
}
})
w := httptest.NewRecorder()
r := new(http.Request)
manager(setupHandler).ServeHTTP(w, r)
sessionCookie := w.Header().Get("Set-Cookie")
r = new(http.Request)
r.Header = make(http.Header)
r.Header.Add("Cookie", sessionCookie)
b.ResetTimer()
for n := 0; n < b.N; n++ {
var nr http.Request
nr = *r
manager(benchHandler).ServeHTTP(w, &nr)
}
}
type User struct {
Name string
Age int
}
func benchSCSObject(b *testing.B, engine session.Engine) {
gob.Register(new(User))
manager := session.Manage(engine)
setupHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
err := session.PutObject(r, "user", &User{"Alex", 33})
if err != nil {
b.Fatal(err)
}
})
benchHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
user := new(User)
err := session.GetObject(r, "user", user)
if err != nil {
b.Fatal(err)
}
user.Age = user.Age + 1
err = session.PutObject(r, "user", user)
if err != nil {
b.Fatal(err)
}
})
w := httptest.NewRecorder()
r := new(http.Request)
manager(setupHandler).ServeHTTP(w, r)
sessionCookie := w.Header().Get("Set-Cookie")
r = new(http.Request)
r.Header = make(http.Header)
r.Header.Add("Cookie", sessionCookie)
b.ResetTimer()
for n := 0; n < b.N; n++ {
var nr http.Request
nr = *r
manager(benchHandler).ServeHTTP(w, &nr)
}
}
func BenchmarkSCSMemstore(b *testing.B) {
benchSCS(b, memstore.New(0))
}
func BenchmarkSCSCookies(b *testing.B) {
keyset, err := cookiestore.NewKeyset(
[]byte("f71dc7e58abab014ddad2652475056f185164d262869c8931b239de52711ba87"),
[]byte("911182cec2f206986c8c82440adb7d17"),
)
if err != nil {
b.Fatal(err)
}
benchSCS(b, cookiestore.New(keyset))
}
func BenchmarkSCSRedis(b *testing.B) {
redisPool := redis.NewPool(func() (redis.Conn, error) {
conn, err := redis.Dial("tcp", os.Getenv("SESSION_REDIS_TEST_ADDR"))
if err != nil {
return nil, err
}
return conn, err
}, 50)
defer redisPool.Close()
benchSCS(b, redisstore.New(redisPool))
}
func BenchmarkSCSPostgres(b *testing.B) {
db, err := sql.Open("postgres", os.Getenv("SESSION_PG_TEST_DSN"))
if err != nil {
b.Fatal(err)
}
defer db.Close()
benchSCS(b, pgstore.New(db, 0))
}
func BenchmarkSCSMySQL(b *testing.B) {
db, err := sql.Open("mysql", os.Getenv("SESSION_MYSQL_TEST_DSN"))
if err != nil {
b.Fatal(err)
}
defer db.Close()
benchSCS(b, mysqlstore.New(db, 0))
}
func BenchmarkSCSObjectMemstore(b *testing.B) {
benchSCSObject(b, memstore.New(0))
}
func BenchmarkSCSObjectCookies(b *testing.B) {
keyset, err := cookiestore.NewKeyset(
[]byte("f71dc7e58abab014ddad2652475056f185164d262869c8931b239de52711ba87"),
[]byte("911182cec2f206986c8c82440adb7d17"),
)
if err != nil {
b.Fatal(err)
}
benchSCSObject(b, cookiestore.New(keyset))
}
func BenchmarkSCSObjectRedis(b *testing.B) {
redisPool := redis.NewPool(func() (redis.Conn, error) {
conn, err := redis.Dial("tcp", os.Getenv("SESSION_REDIS_TEST_ADDR"))
if err != nil {
return nil, err
}
return conn, err
}, 50)
defer redisPool.Close()
benchSCSObject(b, redisstore.New(redisPool))
}
func BenchmarkSCSObjectPostgres(b *testing.B) {
db, err := sql.Open("postgres", os.Getenv("SESSION_PG_TEST_DSN"))
if err != nil {
b.Fatal(err)
}
defer db.Close()
benchSCSObject(b, pgstore.New(db, 0))
}
func BenchmarkSCSObjectMySQL(b *testing.B) {
db, err := sql.Open("mysql", os.Getenv("SESSION_MYSQL_TEST_DSN"))
if err != nil {
b.Fatal(err)
}
defer db.Close()
benchSCSObject(b, mysqlstore.New(db, 0))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment