You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

323 lines
5.8 KiB

  1. package msgpack_test
  2. import (
  3. "bytes"
  4. "math"
  5. "testing"
  6. "time"
  7. "github.com/vmihailenco/msgpack"
  8. )
  9. func benchmarkEncodeDecode(b *testing.B, src, dst interface{}) {
  10. var buf bytes.Buffer
  11. dec := msgpack.NewDecoder(&buf)
  12. enc := msgpack.NewEncoder(&buf)
  13. b.ResetTimer()
  14. for i := 0; i < b.N; i++ {
  15. if err := enc.Encode(src); err != nil {
  16. b.Fatal(err)
  17. }
  18. if err := dec.Decode(dst); err != nil {
  19. b.Fatal(err)
  20. }
  21. }
  22. }
  23. func BenchmarkBool(b *testing.B) {
  24. var dst bool
  25. benchmarkEncodeDecode(b, true, &dst)
  26. }
  27. func BenchmarkInt0(b *testing.B) {
  28. var dst int
  29. benchmarkEncodeDecode(b, 1, &dst)
  30. }
  31. func BenchmarkInt1(b *testing.B) {
  32. var dst int
  33. benchmarkEncodeDecode(b, -33, &dst)
  34. }
  35. func BenchmarkInt2(b *testing.B) {
  36. var dst int
  37. benchmarkEncodeDecode(b, 128, &dst)
  38. }
  39. func BenchmarkInt4(b *testing.B) {
  40. var dst int
  41. benchmarkEncodeDecode(b, 32768, &dst)
  42. }
  43. func BenchmarkInt8(b *testing.B) {
  44. var dst int
  45. benchmarkEncodeDecode(b, int64(2147483648), &dst)
  46. }
  47. func BenchmarkInt32(b *testing.B) {
  48. var dst int32
  49. benchmarkEncodeDecode(b, int32(0), &dst)
  50. }
  51. func BenchmarkTime(b *testing.B) {
  52. var dst time.Time
  53. benchmarkEncodeDecode(b, time.Now(), &dst)
  54. }
  55. func BenchmarkDuration(b *testing.B) {
  56. var dst time.Duration
  57. benchmarkEncodeDecode(b, time.Hour, &dst)
  58. }
  59. func BenchmarkByteSlice(b *testing.B) {
  60. src := make([]byte, 1024)
  61. var dst []byte
  62. benchmarkEncodeDecode(b, src, &dst)
  63. }
  64. func BenchmarkByteArray(b *testing.B) {
  65. var src [1024]byte
  66. var dst [1024]byte
  67. benchmarkEncodeDecode(b, src, &dst)
  68. }
  69. func BenchmarkMapStringString(b *testing.B) {
  70. src := map[string]string{
  71. "hello": "world",
  72. "foo": "bar",
  73. }
  74. var dst map[string]string
  75. benchmarkEncodeDecode(b, src, &dst)
  76. }
  77. func BenchmarkMapStringStringPtr(b *testing.B) {
  78. src := map[string]string{
  79. "hello": "world",
  80. "foo": "bar",
  81. }
  82. var dst map[string]string
  83. dstptr := &dst
  84. benchmarkEncodeDecode(b, src, &dstptr)
  85. }
  86. func BenchmarkMapStringInterface(b *testing.B) {
  87. src := map[string]interface{}{
  88. "hello": "world",
  89. "foo": "bar",
  90. }
  91. var dst map[string]interface{}
  92. benchmarkEncodeDecode(b, src, &dst)
  93. }
  94. func BenchmarkMapIntInt(b *testing.B) {
  95. src := map[int]int{
  96. 1: 10,
  97. 2: 20,
  98. }
  99. var dst map[int]int
  100. benchmarkEncodeDecode(b, src, &dst)
  101. }
  102. func BenchmarkStringSlice(b *testing.B) {
  103. src := []string{"hello", "world"}
  104. var dst []string
  105. benchmarkEncodeDecode(b, src, &dst)
  106. }
  107. func BenchmarkStringSlicePtr(b *testing.B) {
  108. src := []string{"hello", "world"}
  109. var dst []string
  110. dstptr := &dst
  111. benchmarkEncodeDecode(b, src, &dstptr)
  112. }
  113. type benchmarkStruct struct {
  114. Name string
  115. Age int
  116. Colors []string
  117. Data []byte
  118. CreatedAt time.Time
  119. UpdatedAt time.Time
  120. }
  121. type benchmarkStruct2 struct {
  122. Name string
  123. Age int
  124. Colors []string
  125. Data []byte
  126. CreatedAt time.Time
  127. UpdatedAt time.Time
  128. }
  129. var _ msgpack.CustomEncoder = (*benchmarkStruct2)(nil)
  130. var _ msgpack.CustomDecoder = (*benchmarkStruct2)(nil)
  131. func (s *benchmarkStruct2) EncodeMsgpack(enc *msgpack.Encoder) error {
  132. return enc.Encode(
  133. s.Name,
  134. s.Colors,
  135. s.Age,
  136. s.Data,
  137. s.CreatedAt,
  138. s.UpdatedAt,
  139. )
  140. }
  141. func (s *benchmarkStruct2) DecodeMsgpack(dec *msgpack.Decoder) error {
  142. return dec.Decode(
  143. &s.Name,
  144. &s.Colors,
  145. &s.Age,
  146. &s.Data,
  147. &s.CreatedAt,
  148. &s.UpdatedAt,
  149. )
  150. }
  151. func structForBenchmark() *benchmarkStruct {
  152. return &benchmarkStruct{
  153. Name: "Hello World",
  154. Colors: []string{"red", "orange", "yellow", "green", "blue", "violet"},
  155. Age: math.MaxInt32,
  156. Data: make([]byte, 1024),
  157. CreatedAt: time.Now(),
  158. UpdatedAt: time.Now(),
  159. }
  160. }
  161. func structForBenchmark2() *benchmarkStruct2 {
  162. return &benchmarkStruct2{
  163. Name: "Hello World",
  164. Colors: []string{"red", "orange", "yellow", "green", "blue", "violet"},
  165. Age: math.MaxInt32,
  166. Data: make([]byte, 1024),
  167. CreatedAt: time.Now(),
  168. UpdatedAt: time.Now(),
  169. }
  170. }
  171. func BenchmarkStructVmihailencoMsgpack(b *testing.B) {
  172. in := structForBenchmark()
  173. out := new(benchmarkStruct)
  174. b.ResetTimer()
  175. for i := 0; i < b.N; i++ {
  176. buf, err := msgpack.Marshal(in)
  177. if err != nil {
  178. b.Fatal(err)
  179. }
  180. err = msgpack.Unmarshal(buf, out)
  181. if err != nil {
  182. b.Fatal(err)
  183. }
  184. }
  185. }
  186. func BenchmarkStructMarshal(b *testing.B) {
  187. in := structForBenchmark()
  188. b.ResetTimer()
  189. for i := 0; i < b.N; i++ {
  190. _, err := msgpack.Marshal(in)
  191. if err != nil {
  192. b.Fatal(err)
  193. }
  194. }
  195. }
  196. func BenchmarkStructUnmarshal(b *testing.B) {
  197. in := structForBenchmark()
  198. buf, err := msgpack.Marshal(in)
  199. if err != nil {
  200. b.Fatal(err)
  201. }
  202. out := new(benchmarkStruct)
  203. b.ResetTimer()
  204. for i := 0; i < b.N; i++ {
  205. err = msgpack.Unmarshal(buf, out)
  206. if err != nil {
  207. b.Fatal(err)
  208. }
  209. }
  210. }
  211. func BenchmarkStructManual(b *testing.B) {
  212. in := structForBenchmark2()
  213. out := new(benchmarkStruct2)
  214. b.ResetTimer()
  215. for i := 0; i < b.N; i++ {
  216. buf, err := msgpack.Marshal(in)
  217. if err != nil {
  218. b.Fatal(err)
  219. }
  220. err = msgpack.Unmarshal(buf, out)
  221. if err != nil {
  222. b.Fatal(err)
  223. }
  224. }
  225. }
  226. type benchmarkStructPartially struct {
  227. Name string
  228. Age int
  229. }
  230. func BenchmarkStructUnmarshalPartially(b *testing.B) {
  231. in := structForBenchmark()
  232. buf, err := msgpack.Marshal(in)
  233. if err != nil {
  234. b.Fatal(err)
  235. }
  236. out := new(benchmarkStructPartially)
  237. b.ResetTimer()
  238. for i := 0; i < b.N; i++ {
  239. err = msgpack.Unmarshal(buf, out)
  240. if err != nil {
  241. b.Fatal(err)
  242. }
  243. }
  244. }
  245. func BenchmarkQuery(b *testing.B) {
  246. var records []map[string]interface{}
  247. for i := 0; i < 1000; i++ {
  248. record := map[string]interface{}{
  249. "id": i,
  250. "attrs": map[string]interface{}{"phone": i},
  251. }
  252. records = append(records, record)
  253. }
  254. bs, err := msgpack.Marshal(records)
  255. if err != nil {
  256. b.Fatal(err)
  257. }
  258. dec := msgpack.NewDecoder(bytes.NewBuffer(bs))
  259. b.ResetTimer()
  260. for i := 0; i < b.N; i++ {
  261. dec.Reset(bytes.NewBuffer(bs))
  262. values, err := dec.Query("10.attrs.phone")
  263. if err != nil {
  264. b.Fatal(err)
  265. }
  266. if values[0].(int8) != 10 {
  267. b.Fatalf("%v != %d", values[0], 10)
  268. }
  269. }
  270. }