Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Use typeswitch instead of reflection on slices of basic type
- The effects of this patch should be even more pronounced in larger slices
- because of the increased overhead of doing reflection on each element
- Benchmarks
- Before:
- BenchmarkWriteSlice1000Int32s 10000 117373 ns/op 34.08 MB/s
- After:
- BenchmarkWriteSlice1000Int32s 100000 23536 ns/op 169.95 MB/s
- --- a/src/pkg/encoding/binary/binary.go Fri Dec 23 14:28:01 2011 +1100
- +++ b/src/pkg/encoding/binary/binary.go Tue Jan 10 23:17:29 2012 +0100
- @@ -417,6 +417,55 @@
- }
- }
- +//this handles the slices of basic types without
- +//having to reflect on each value
- +func (e *encoder) commonSlices(value reflect.Value) bool {
- + i := value.Interface()
- + switch v := i.(type) {
- + case []uint8:
- + for _, elem := range v {
- + e.uint8(elem)
- + }
- + return true
- + case []int8:
- + for _, elem := range v {
- + e.int8(elem)
- + }
- + return true
- + case []uint16:
- + for _, elem := range v {
- + e.uint16(elem)
- + }
- + return true
- + case []int16:
- + for _, elem := range v {
- + e.int16(elem)
- + }
- + return true
- + case []uint32:
- + for _, elem := range v {
- + e.uint32(elem)
- + }
- + return true
- + case []int32:
- + for _, elem := range v {
- + e.int32(elem)
- + }
- + return true
- + case []uint64:
- + for _, elem := range v {
- + e.uint64(elem)
- + }
- + return true
- + case []int64:
- + for _, elem := range v {
- + e.int64(elem)
- + }
- + return true
- + }
- + return false
- +}
- +
- func (e *encoder) value(v reflect.Value) {
- switch v.Kind() {
- case reflect.Array:
- @@ -430,6 +479,9 @@
- e.value(v.Field(i))
- }
- case reflect.Slice:
- + if e.commonSlices(v) {
- + return
- + }
- l := v.Len()
- for i := 0; i < l; i++ {
- e.value(v.Index(i))
- diff -r 4a8268927758 -r 4013fd3724fb src/pkg/encoding/binary/binary_test.go
- --- a/src/pkg/encoding/binary/binary_test.go Fri Dec 23 14:28:01 2011 +1100
- +++ b/src/pkg/encoding/binary/binary_test.go Tue Jan 10 23:17:29 2012 +0100
- @@ -183,6 +183,23 @@
- }
- }
- +type nullWriter int
- +
- +func (nwr nullWriter) Write(b []byte) (n int, err error) {
- + n = len(b)
- + return
- +}
- +
- +func BenchmarkWriteSlice1000Int32s(b *testing.B) {
- + var nwr nullWriter
- + slice := make([]int32, 1000)
- + b.SetBytes(int64(len(slice)*4))
- + b.ResetTimer()
- + for i := 0; i < b.N; i++ {
- + Write(nwr, BigEndian, slice)
- + }
- +}
- +
- func BenchmarkReadStruct(b *testing.B) {
- bsr := &byteSliceReader{}
- var buf bytes.Buffer
Add Comment
Please, Sign In to add comment