Last active
August 29, 2015 14:27
-
-
Save rhcarvalho/abb12fa958f3e83537cf to your computer and use it in GitHub Desktop.
Compare sorting structs and pointer to structs
This file contains hidden or 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
| $ go test -bench . -benchmem | |
| testing: warning: no tests to run | |
| PASS | |
| BenchmarkVal5 10000000 161 ns/op 32 B/op 1 allocs/op | |
| BenchmarkPtr5 10000000 152 ns/op 32 B/op 1 allocs/op | |
| BenchmarkValFromPtr5 1000000 2280 ns/op 1312 B/op 2 allocs/op | |
| BenchmarkPtrFromVal5 3000000 334 ns/op 80 B/op 2 allocs/op | |
| BenchmarkVal50 300000 4120 ns/op 32 B/op 1 allocs/op | |
| BenchmarkPtr50 500000 3174 ns/op 32 B/op 1 allocs/op | |
| BenchmarkValFromPtr50 100000 19084 ns/op 12320 B/op 2 allocs/op | |
| BenchmarkPtrFromVal50 300000 6024 ns/op 448 B/op 2 allocs/op | |
| BenchmarkVal500 20000 66041 ns/op 32 B/op 1 allocs/op | |
| BenchmarkPtr500 30000 55028 ns/op 32 B/op 1 allocs/op | |
| BenchmarkValFromPtr500 5000 254824 ns/op 122912 B/op 2 allocs/op | |
| BenchmarkPtrFromVal500 10000 109946 ns/op 4128 B/op 2 allocs/op | |
| BenchmarkVal5k 2000 893099 ns/op 32 B/op 1 allocs/op | |
| BenchmarkPtr5k 2000 842924 ns/op 32 B/op 1 allocs/op | |
| BenchmarkValFromPtr5k 500 3688927 ns/op 1163296 B/op 2 allocs/op | |
| BenchmarkPtrFromVal5k 1000 1693813 ns/op 40992 B/op 2 allocs/op | |
| BenchmarkVal50k 100 12503727 ns/op 32 B/op 1 allocs/op | |
| BenchmarkPtr50k 50 23618415 ns/op 32 B/op 1 allocs/op | |
| BenchmarkValFromPtr50k 30 48661713 ns/op 11608096 B/op 2 allocs/op | |
| BenchmarkPtrFromVal50k 50 27468791 ns/op 401440 B/op 2 allocs/op | |
| ok 97.521s |
This file contains hidden or 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
| package test | |
| import ( | |
| "math/rand" | |
| "sort" | |
| "testing" | |
| "time" | |
| ) | |
| type Blob struct { | |
| Name string | |
| Value int | |
| CreationTimestamp time.Time | |
| ptr1 *Blob | |
| ptr2 *Blob | |
| ptr3 *Blob | |
| ptr4 *Blob | |
| ptr5 *Blob | |
| ptr6 *Blob | |
| ptr7 *Blob | |
| ptr8 *Blob | |
| ptr9 *Blob | |
| ptr10 *Blob | |
| ptr11 *Blob | |
| ptr12 *Blob | |
| ptr13 *Blob | |
| ptr14 *Blob | |
| ptr15 *Blob | |
| ptr16 *Blob | |
| ptr17 *Blob | |
| ptr18 *Blob | |
| ptr19 *Blob | |
| ptr20 *Blob | |
| ptr21 *Blob | |
| ptr22 *Blob | |
| ptr23 *Blob | |
| } | |
| type BlobSliceByCreationTimestamp []Blob | |
| func (s BlobSliceByCreationTimestamp) Len() int { | |
| return len(s) | |
| } | |
| func (s BlobSliceByCreationTimestamp) Swap(i, j int) { | |
| s[i], s[j] = s[j], s[i] | |
| } | |
| func (s BlobSliceByCreationTimestamp) Less(i, j int) bool { | |
| return s[i].CreationTimestamp.Before(s[j].CreationTimestamp) | |
| } | |
| type BlobPointerSliceByCreationTimestamp []*Blob | |
| func (s BlobPointerSliceByCreationTimestamp) Len() int { | |
| return len(s) | |
| } | |
| func (s BlobPointerSliceByCreationTimestamp) Swap(i, j int) { | |
| s[i], s[j] = s[j], s[i] | |
| } | |
| func (s BlobPointerSliceByCreationTimestamp) Less(i, j int) bool { | |
| return s[i].CreationTimestamp.Before(s[j].CreationTimestamp) | |
| } | |
| const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" | |
| func RandStringBytes(n int) string { | |
| b := make([]byte, n) | |
| for i := range b { | |
| b[i] = letters[rand.Intn(len(letters))] | |
| } | |
| return string(b) | |
| } | |
| func newRandomBlob() Blob { | |
| return Blob{ | |
| RandStringBytes(100 + rand.Intn(5000)), | |
| rand.Intn(987654), | |
| time.Now().Add(time.Duration(rand.Int31()) * time.Microsecond), | |
| &Blob{}, | |
| &Blob{}, | |
| &Blob{}, | |
| &Blob{}, | |
| &Blob{}, | |
| &Blob{}, | |
| &Blob{}, | |
| &Blob{}, | |
| &Blob{}, | |
| &Blob{}, | |
| &Blob{}, | |
| &Blob{}, | |
| &Blob{}, | |
| &Blob{}, | |
| &Blob{}, | |
| &Blob{}, | |
| &Blob{}, | |
| &Blob{}, | |
| &Blob{}, | |
| &Blob{}, | |
| &Blob{}, | |
| &Blob{}, | |
| &Blob{}, | |
| } | |
| } | |
| func newRandomBlobSlice(size int) []Blob { | |
| s := make([]Blob, size) | |
| for i := range s { | |
| s[i] = newRandomBlob() | |
| } | |
| return s | |
| } | |
| func newRandomBlobPointerSlice(size int) []*Blob { | |
| s := make([]*Blob, size) | |
| for i := range s { | |
| blob := newRandomBlob() | |
| s[i] = &blob | |
| } | |
| return s | |
| } | |
| // sort []Blob without conversion | |
| func benchVal(b *testing.B, size int) { | |
| // initialize data | |
| s := newRandomBlobSlice(size) | |
| // ignore time spent on initialization | |
| b.ResetTimer() | |
| for i := 0; i < b.N; i++ { | |
| sort.Sort(BlobSliceByCreationTimestamp(s)) | |
| } | |
| } | |
| // sort []*Blob without conversion | |
| func benchPtr(b *testing.B, size int) { | |
| // initialize data | |
| ps := newRandomBlobPointerSlice(size) | |
| // ignore time spent on initialization | |
| b.ResetTimer() | |
| for i := 0; i < b.N; i++ { | |
| sort.Sort(BlobPointerSliceByCreationTimestamp(ps)) | |
| } | |
| } | |
| // sort []Blob with conversion from []*Blob | |
| func benchValFromPtr(b *testing.B, size int) { | |
| // initialize data | |
| ps := newRandomBlobPointerSlice(size) | |
| // ignore time spent on initialization | |
| b.ResetTimer() | |
| for i := 0; i < b.N; i++ { | |
| s := make([]Blob, len(ps)) | |
| for i := range ps { | |
| s[i] = *ps[i] | |
| } | |
| sort.Sort(BlobSliceByCreationTimestamp(s)) | |
| } | |
| } | |
| // sort []*Blob with conversion []Blob | |
| func benchPtrFromVal(b *testing.B, size int) { | |
| // initialize data | |
| s := newRandomBlobSlice(size) | |
| // ignore time spent on initialization | |
| b.ResetTimer() | |
| for i := 0; i < b.N; i++ { | |
| ps := make([]*Blob, len(s)) | |
| for i := range s { | |
| ps[i] = &s[i] | |
| } | |
| sort.Sort(BlobPointerSliceByCreationTimestamp(ps)) | |
| } | |
| } | |
| func BenchmarkVal5(b *testing.B) { benchVal(b, 5) } | |
| func BenchmarkPtr5(b *testing.B) { benchPtr(b, 5) } | |
| func BenchmarkValFromPtr5(b *testing.B) { benchValFromPtr(b, 5) } | |
| func BenchmarkPtrFromVal5(b *testing.B) { benchPtrFromVal(b, 5) } | |
| func BenchmarkVal50(b *testing.B) { benchVal(b, 50) } | |
| func BenchmarkPtr50(b *testing.B) { benchPtr(b, 50) } | |
| func BenchmarkValFromPtr50(b *testing.B) { benchValFromPtr(b, 50) } | |
| func BenchmarkPtrFromVal50(b *testing.B) { benchPtrFromVal(b, 50) } | |
| func BenchmarkVal500(b *testing.B) { benchVal(b, 500) } | |
| func BenchmarkPtr500(b *testing.B) { benchPtr(b, 500) } | |
| func BenchmarkValFromPtr500(b *testing.B) { benchValFromPtr(b, 500) } | |
| func BenchmarkPtrFromVal500(b *testing.B) { benchPtrFromVal(b, 500) } | |
| func BenchmarkVal5k(b *testing.B) { benchVal(b, 5000) } | |
| func BenchmarkPtr5k(b *testing.B) { benchPtr(b, 5000) } | |
| func BenchmarkValFromPtr5k(b *testing.B) { benchValFromPtr(b, 5000) } | |
| func BenchmarkPtrFromVal5k(b *testing.B) { benchPtrFromVal(b, 5000) } | |
| func BenchmarkVal50k(b *testing.B) { benchVal(b, 50000) } | |
| func BenchmarkPtr50k(b *testing.B) { benchPtr(b, 50000) } | |
| func BenchmarkValFromPtr50k(b *testing.B) { benchValFromPtr(b, 50000) } | |
| func BenchmarkPtrFromVal50k(b *testing.B) { benchPtrFromVal(b, 50000) } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment