map_test.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. package test
  2. import (
  3. "testing"
  4. "github.com/modern-go/reflect2"
  5. "github.com/modern-go/test/must"
  6. "github.com/modern-go/test"
  7. "unsafe"
  8. "reflect"
  9. "context"
  10. )
  11. func Test_map(t *testing.T) {
  12. var pInt = func(val int) *int {
  13. return &val
  14. }
  15. t.Run("New", testOp(func(api reflect2.API) interface{} {
  16. valType := api.TypeOf(map[int]int{})
  17. m := valType.New().(*map[int]int)
  18. return m
  19. }))
  20. t.Run("IsNil", testOp(func(api reflect2.API) interface{} {
  21. valType := api.TypeOf(map[int]int{})
  22. var nilMap map[int]int
  23. m := map[int]int{}
  24. return []interface{}{
  25. valType.IsNil(&nilMap),
  26. valType.IsNil(&m),
  27. }
  28. }))
  29. t.Run("MakeMap", testOp(func(api reflect2.API) interface{} {
  30. valType := api.TypeOf(map[int]int{}).(reflect2.MapType)
  31. m := *(valType.MakeMap(0).(*map[int]int))
  32. m[2] = 4
  33. m[3] = 9
  34. return m
  35. }))
  36. t.Run("UnsafeMakeMap", test.Case(func(ctx context.Context) {
  37. valType := reflect2.TypeOf(map[int]int{}).(reflect2.MapType)
  38. m := *(*map[int]int)(valType.UnsafeMakeMap(0))
  39. m[2] = 4
  40. m[3] = 9
  41. }))
  42. t.Run("PackEFace", test.Case(func(ctx context.Context) {
  43. valType := reflect2.TypeOf(map[int]int{}).(reflect2.MapType)
  44. m := valType.UnsafeMakeMap(0)
  45. must.Equal(&map[int]int{}, valType.PackEFace(unsafe.Pointer(m)))
  46. }))
  47. t.Run("Indirect", testOp(func(api reflect2.API) interface{} {
  48. valType := reflect2.TypeOf(map[int]int{})
  49. return valType.Indirect(&map[int]int{})
  50. }))
  51. t.Run("SetIndex", testOp(func(api reflect2.API) interface{} {
  52. obj := map[int]int{}
  53. valType := api.TypeOf(obj).(reflect2.MapType)
  54. valType.SetIndex(&obj, pInt(2), pInt(4))
  55. valType.SetIndex(&obj, pInt(3), pInt(9))
  56. must.Equal(4, obj[2])
  57. return obj
  58. }))
  59. t.Run("UnsafeSetIndex", test.Case(func(ctx context.Context) {
  60. obj := map[int]int{}
  61. valType := reflect2.TypeOf(obj).(reflect2.MapType)
  62. valType.UnsafeSetIndex(unsafe.Pointer(&obj), reflect2.PtrOf(2), reflect2.PtrOf(4))
  63. must.Equal(map[int]int{2: 4}, obj)
  64. }))
  65. t.Run("GetIndex", testOp(func(api reflect2.API) interface{} {
  66. obj := map[int]int{3: 9, 2: 4}
  67. valType := api.TypeOf(obj).(reflect2.MapType)
  68. return []interface{}{
  69. *valType.GetIndex(&obj, pInt(3)).(*int),
  70. valType.GetIndex(&obj, pInt(0)).(*int),
  71. }
  72. }))
  73. t.Run("UnsafeGetIndex", test.Case(func(ctx context.Context) {
  74. obj := map[int]int{3: 9, 2: 4}
  75. valType := reflect2.TypeOf(obj).(reflect2.MapType)
  76. elem := valType.UnsafeGetIndex(unsafe.Pointer(&obj), reflect2.PtrOf(3))
  77. must.Equal(9, *(*int)(elem))
  78. }))
  79. t.Run("Iterate", testOp(func(api reflect2.API) interface{} {
  80. obj := map[int]int{2: 4}
  81. valType := api.TypeOf(obj).(reflect2.MapType)
  82. iter := valType.Iterate(&obj)
  83. must.Pass(iter.HasNext(), "api", api)
  84. key1, elem1 := iter.Next()
  85. must.Pass(!iter.HasNext(), "api", api)
  86. return []interface{}{key1, elem1}
  87. }))
  88. t.Run("UnsafeIterate", test.Case(func(ctx context.Context) {
  89. obj := map[int]int{2: 4}
  90. valType := reflect2.TypeOf(obj).(reflect2.MapType)
  91. iter := valType.UnsafeIterate(unsafe.Pointer(&obj))
  92. must.Pass(iter.HasNext())
  93. key, elem := iter.UnsafeNext()
  94. must.Equal(2, *(*int)(key))
  95. must.Equal(4, *(*int)(elem))
  96. }))
  97. }
  98. func Benchmark_map_unsafe(b *testing.B) {
  99. obj := map[int]int{}
  100. valType := reflect2.TypeOf(obj).(*reflect2.UnsafeMapType)
  101. m := unsafe.Pointer(&obj)
  102. b.ReportAllocs()
  103. b.ResetTimer()
  104. for i := 0; i < b.N; i++ {
  105. valType.UnsafeSetIndex(m, reflect2.PtrOf(2), reflect2.PtrOf(4))
  106. }
  107. }
  108. func Benchmark_map_safe(b *testing.B) {
  109. obj := map[int]int{}
  110. val := reflect.ValueOf(obj)
  111. b.ReportAllocs()
  112. b.ResetTimer()
  113. for i := 0; i < b.N; i++ {
  114. val.SetMapIndex(reflect.ValueOf(2), reflect.ValueOf(4))
  115. }
  116. }