構造体のスライス([]Person)を関数の引数として渡すとき、スライス要素の構造体のコピーが起こらないように、[]Personではなく[]*Personのようにしました。(ソースコードは1番下です)
調べてみたところ、スライスを引数に渡しても要素自体はコピーされないとのことだったのですが、引数の型の違いでベンチマークに違いが出ていました。
以下に4回分のベンチマークの結果を載せます。
1
1BenchmarkA-6 565 2143826 ns/op 2196458 B/op 19401 allocs/op 2BenchmarkB-6 549 2221813 ns/op 2016721 B/op 24241 allocs/op 3BenchmarkC-6 561 2111836 ns/op 2196518 B/op 19403 allocs/op 4BenchmarkD-6 540 2188856 ns/op 2016780 B/op 24243 allocs/op
2
1BenchmarkA-6 538 2161718 ns/op 2196458 B/op 19401 allocs/op 2BenchmarkB-6 541 2234250 ns/op 2016715 B/op 24241 allocs/op 3BenchmarkC-6 566 2131299 ns/op 2196509 B/op 19403 allocs/op 4BenchmarkD-6 538 2223253 ns/op 2016782 B/op 24243 allocs/op
3
1BenchmarkA-6 552 2258949 ns/op 2196457 B/op 19401 allocs/op 2BenchmarkB-6 511 2225532 ns/op 2016711 B/op 24241 allocs/op 3BenchmarkC-6 537 2195281 ns/op 2196499 B/op 19403 allocs/op 4BenchmarkD-6 535 2236069 ns/op 2016787 B/op 24243 allocs/op
4
1BenchmarkA-6 554 2279453 ns/op 2196468 B/op 19401 allocs/op 2BenchmarkB-6 525 2234598 ns/op 2016723 B/op 24241 allocs/op 3BenchmarkC-6 544 2158688 ns/op 2196510 B/op 19403 allocs/op 4BenchmarkD-6 523 2262048 ns/op 2016791 B/op 24243 allocs/op
割り当てメモリサイズはどちらも変わらないと思っていたのですが、ポインタ渡しの方が少なくなっています。
また、実行速度はポインタ渡しの方が遅くなっていますが、どのあたりで速度が落ちているのでしょうか。
メモリ割り当て回数が増えているのでそれが関係していると思うのですが、どのあたりでメモリ割り当てが起こっているのでしょうか?
以下にソースコードを載せます。
A:[]Person
B:[]Person
C:[]Person
D:*[]*Person
go
1package test 2 3import ( 4 "bufio" 5 "fmt" 6 "os" 7 "strconv" 8 "strings" 9 "testing" 10) 11 12const fileName = "test.dat" 13 14var bodyInfo []string = []string{"height", "weight", "age"} 15 16type Person struct { 17 name string 18 body map[string]int 19} 20 21func inputA() []Person { 22 var ps []Person 23 f, _ := os.Open(fileName) 24 defer f.Close() 25 26 s := bufio.NewScanner(f) 27 28 for s.Scan() { 29 p := Person{} 30 p.body = make(map[string]int) 31 data := strings.Split(s.Text(), ",") 32 p.name = data[0] 33 for i := 0; i < 3; i++ { 34 p.body[bodyInfo[i]], _ = strconv.Atoi(data[i+1]) 35 } 36 ps = append(ps, p) 37 } 38 return ps 39} 40 41func inputB() []*Person { 42 var ps []*Person 43 f, _ := os.Open(fileName) 44 defer f.Close() 45 46 s := bufio.NewScanner(f) 47 48 for s.Scan() { 49 p := &Person{} 50 p.body = make(map[string]int) 51 data := strings.Split(s.Text(), ",") 52 p.name = data[0] 53 for i := 0; i < 3; i++ { 54 p.body[bodyInfo[i]], _ = strconv.Atoi(data[i+1]) 55 } 56 ps = append(ps, p) 57 } 58 return ps 59} 60 61func inputC() *[]Person { 62 var ps []Person 63 f, _ := os.Open(fileName) 64 defer f.Close() 65 66 s := bufio.NewScanner(f) 67 68 for s.Scan() { 69 p := Person{} 70 p.body = make(map[string]int) 71 data := strings.Split(s.Text(), ",") 72 p.name = data[0] 73 for i := 0; i < 3; i++ { 74 p.body[bodyInfo[i]], _ = strconv.Atoi(data[i+1]) 75 } 76 ps = append(ps, p) 77 } 78 return &ps 79} 80 81func inputD() *[]*Person { 82 var ps []*Person 83 f, _ := os.Open(fileName) 84 defer f.Close() 85 86 s := bufio.NewScanner(f) 87 88 for s.Scan() { 89 p := &Person{} 90 p.body = make(map[string]int) 91 data := strings.Split(s.Text(), ",") 92 p.name = data[0] 93 for i := 0; i < 3; i++ { 94 p.body[bodyInfo[i]], _ = strconv.Atoi(data[i+1]) 95 } 96 ps = append(ps, p) 97 } 98 return &ps 99} 100 101func A(ps []Person) []Person { 102 var nps []Person 103 104 for _, v := range ps { 105 if v.body["height"] >= 180 && v.body["weight"] >= 80 && v.body["age"] >= 20 { 106 nps = append(nps, v) 107 } 108 } 109 return nps 110} 111 112func B(ps []*Person) []*Person { 113 var nps []*Person 114 115 for _, v := range ps { 116 if v.body["height"] >= 180 && v.body["weight"] >= 80 && v.body["age"] >= 20 { 117 nps = append(nps, v) 118 } 119 } 120 return nps 121} 122 123func C(ps *[]Person) *[]Person { 124 var nps []Person 125 126 for _, v := range *ps { 127 if v.body["height"] >= 180 && v.body["weight"] >= 80 && v.body["age"] >= 20 { 128 nps = append(nps, v) 129 } 130 } 131 return &nps 132} 133 134func D(ps *[]*Person) *[]*Person { 135 var nps []*Person 136 137 for _, v := range *ps { 138 if v.body["height"] >= 180 && v.body["weight"] >= 80 && v.body["age"] >= 20 { 139 nps = append(nps, v) 140 } 141 } 142 return &nps 143} 144 145func BenchmarkA(b *testing.B) { 146 b.ResetTimer() 147 for i := 0; i < b.N; i++ { 148 ps := inputA() 149 nps := A(ps) 150 f, _ := os.Create(fmt.Sprintf("./A/%d.dat", i)) 151 w := bufio.NewWriter(f) 152 for _, v := range nps { 153 w.WriteString(v.name + "\n") 154 } 155 w.Flush() 156 f.Close() 157 } 158} 159 160func BenchmarkB(b *testing.B) { 161 b.ResetTimer() 162 for i := 0; i < b.N; i++ { 163 ps := inputB() 164 nps := B(ps) 165 f, _ := os.Create(fmt.Sprintf("./B/%d.dat", i)) 166 w := bufio.NewWriter(f) 167 for _, v := range nps { 168 w.WriteString(v.name + "\n") 169 } 170 w.Flush() 171 f.Close() 172 } 173} 174 175func BenchmarkC(b *testing.B) { 176 b.ResetTimer() 177 for i := 0; i < b.N; i++ { 178 ps := inputC() 179 nps := C(ps) 180 f, _ := os.Create(fmt.Sprintf("./C/%d.dat", i)) 181 w := bufio.NewWriter(f) 182 for _, v := range *nps { 183 w.WriteString(v.name + "\n") 184 } 185 w.Flush() 186 f.Close() 187 } 188} 189 190func BenchmarkD(b *testing.B) { 191 b.ResetTimer() 192 for i := 0; i < b.N; i++ { 193 ps := inputD() 194 nps := D(ps) 195 f, _ := os.Create(fmt.Sprintf("./D/%d.dat", i)) 196 w := bufio.NewWriter(f) 197 for _, v := range *nps { 198 w.WriteString(v.name + "\n") 199 } 200 w.Flush() 201 f.Close() 202 } 203} 204
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。