Skip to content

Instantly share code, notes, and snippets.

@jonhoo
Created April 15, 2015 21:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jonhoo/30104978fe1c87e68f3b to your computer and use it in GitHub Desktop.
Save jonhoo/30104978fe1c87e68f3b to your computer and use it in GitHub Desktop.
Go slices and `interface{}`s

When passing Go slices through interface{} values, beware that this slows your application down. If possible, you should instead be passing around pointers to slices, and dereference them after the cast:

$ go test -c
$ ./x.test -test.bench . -test.run Benchmark -test.benchtime 3s
BenchmarkInterfaceSlice		30000000	        148 ns/op
BenchmarkInterfaceSlicePtr	300000000	       14.0 ns/op
$ go tool pprof -text -cum x.test slice.out | grep -vE 'testing|goexit|Benchmark'
4420ms of 4610ms total (95.88%)
Dropped 16 nodes (cum <= 23.05ms)
      flat  flat%   sum%        cum   cum%
         0     0%     0%     2100ms 45.55%  GC
     180ms  3.90%  8.03%     1550ms 33.62%  runtime.convT2E
    1400ms 30.37% 38.39%     1400ms 30.37%  scanblock
     140ms  3.04% 41.43%     1070ms 23.21%  runtime.newobject
     730ms 15.84% 57.27%      930ms 20.17%  runtime.mallocgc
     800ms 17.35% 74.62%      800ms 17.35%  runtime.MSpan_Sweep
         0     0% 74.62%      580ms 12.58%  System
     290ms  6.29% 80.91%      290ms  6.29%  runtime.memmove
     240ms  5.21% 86.12%      240ms  5.21%  runtime.writebarrierptr
      70ms  1.52% 87.64%      190ms  4.12%  runtime.assertE2T
      80ms  1.74% 89.37%       80ms  1.74%  runtime.readvarint
      60ms  1.30% 90.67%       60ms  1.30%  runtime.futex
      50ms  1.08% 91.76%       50ms  1.08%  runtime.gentraceback
      50ms  1.08% 92.84%       50ms  1.08%  runtime.memclr
      40ms  0.87% 93.71%       40ms  0.87%  runtime.usleep
      40ms  0.87% 94.58%       40ms  0.87%  runtime.xchg
      30ms  0.65% 95.23%       30ms  0.65%  runtime.gomcache
      30ms  0.65% 95.88%       30ms  0.65%  runtime.step
$ go tool pprof -text -cum x.test slice-ptr.out | grep -vE 'testing|goexit|Benchmark'
4200ms of 4200ms total (  100%)
      flat  flat%   sum%        cum   cum%
     780ms 18.57% 89.29%     1230ms 29.29%  runtime.assertE2T
     450ms 10.71%   100%      450ms 10.71%  runtime.memmove
package main
import (
"os"
"runtime/pprof"
"testing"
)
func BenchmarkInterfaceSlice(b *testing.B) {
o, _ := os.Create("slice.out")
pprof.StartCPUProfile(o)
s := make([]int, 0)
var v interface{}
for i := 0; i < b.N; i++ {
v = s
s = v.([]int)
}
pprof.StopCPUProfile()
o.Close()
}
func BenchmarkInterfaceSlicePtr(b *testing.B) {
o, _ := os.Create("slice-ptr.out")
pprof.StartCPUProfile(o)
s := make([]int, 0)
var v interface{}
for i := 0; i < b.N; i++ {
v = &s
s = *v.(*[]int)
}
pprof.StopCPUProfile()
o.Close()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment