Guest User

Untitled

a guest
May 20th, 2018
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 2.42 KB | None | 0 0
  1. Use typeswitch instead of reflection on slices of basic type
  2.  
  3. The effects of this patch should be even more pronounced in larger slices
  4. because of the increased overhead of doing reflection on each element
  5.  
  6. Benchmarks
  7.  
  8. Before:
  9. BenchmarkWriteSlice1000Int32s      10000        117373 ns/op      34.08 MB/s
  10. After:
  11. BenchmarkWriteSlice1000Int32s     100000         23536 ns/op     169.95 MB/s
  12.  
  13. --- a/src/pkg/encoding/binary/binary.go Fri Dec 23 14:28:01 2011 +1100
  14. +++ b/src/pkg/encoding/binary/binary.go Tue Jan 10 23:17:29 2012 +0100
  15. @@ -417,6 +417,55 @@
  16.     }
  17.  }
  18.  
  19. +//this handles the slices of basic types without
  20. +//having to reflect on each value
  21. +func (e *encoder) commonSlices(value reflect.Value) bool {
  22. +   i := value.Interface()
  23. +   switch v := i.(type) {
  24. +   case []uint8:
  25. +       for _, elem := range v {
  26. +           e.uint8(elem)
  27. +       }
  28. +       return true
  29. +   case []int8:
  30. +       for _, elem := range v {
  31. +           e.int8(elem)
  32. +       }
  33. +       return true
  34. +   case []uint16:
  35. +       for _, elem := range v {
  36. +           e.uint16(elem)
  37. +       }
  38. +       return true
  39. +   case []int16:
  40. +       for _, elem := range v {
  41. +           e.int16(elem)
  42. +       }
  43. +       return true
  44. +   case []uint32:
  45. +       for _, elem := range v {
  46. +           e.uint32(elem)
  47. +       }
  48. +       return true
  49. +   case []int32:
  50. +       for _, elem := range v {
  51. +           e.int32(elem)
  52. +       }
  53. +       return true
  54. +   case []uint64:
  55. +       for _, elem := range v {
  56. +           e.uint64(elem)
  57. +       }
  58. +       return true
  59. +   case []int64:
  60. +       for _, elem := range v {
  61. +           e.int64(elem)
  62. +       }
  63. +       return true
  64. +   }
  65. +   return false
  66. +}
  67. +
  68.  func (e *encoder) value(v reflect.Value) {
  69.     switch v.Kind() {
  70.     case reflect.Array:
  71. @@ -430,6 +479,9 @@
  72.             e.value(v.Field(i))
  73.         }
  74.     case reflect.Slice:
  75. +       if e.commonSlices(v) {
  76. +           return
  77. +       }
  78.         l := v.Len()
  79.         for i := 0; i < l; i++ {
  80.             e.value(v.Index(i))
  81. diff -r 4a8268927758 -r 4013fd3724fb src/pkg/encoding/binary/binary_test.go
  82. --- a/src/pkg/encoding/binary/binary_test.go    Fri Dec 23 14:28:01 2011 +1100
  83. +++ b/src/pkg/encoding/binary/binary_test.go    Tue Jan 10 23:17:29 2012 +0100
  84. @@ -183,6 +183,23 @@
  85.     }
  86.  }
  87.  
  88. +type nullWriter int
  89. +
  90. +func (nwr nullWriter) Write(b []byte) (n int, err error) {
  91. +   n = len(b)
  92. +   return
  93. +}
  94. +
  95. +func BenchmarkWriteSlice1000Int32s(b *testing.B) {
  96. +   var nwr nullWriter
  97. +   slice := make([]int32, 1000)
  98. +   b.SetBytes(int64(len(slice)*4))
  99. +   b.ResetTimer()
  100. +   for i := 0; i < b.N; i++ {
  101. +       Write(nwr, BigEndian, slice)
  102. +   }
  103. +}
  104. +
  105.  func BenchmarkReadStruct(b *testing.B) {
  106.     bsr := &byteSliceReader{}
  107.     var buf bytes.Buffer
Add Comment
Please, Sign In to add comment