├── .gitignore ├── go.mod └── perf_test.go /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea 3 | *.iml 4 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module pointer_value_param_perf 2 | 3 | go 1.15 4 | -------------------------------------------------------------------------------- /perf_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "testing" 4 | 5 | var x byte 6 | 7 | //go:noinline 8 | func BenchmarkPointer10In(b *testing.B) { 9 | var v v10 10 | for i := 0; i < b.N; i++ { 11 | readMiddle10p(&v) 12 | } 13 | } 14 | 15 | //go:noinline 16 | func BenchmarkValue10In(b *testing.B) { 17 | var v v10 18 | for i := 0; i < b.N; i++ { 19 | readMiddle10(v) 20 | } 21 | } 22 | 23 | //go:noinline 24 | func BenchmarkPointer10Out(b *testing.B) { 25 | for i := 0; i < b.N; i++ { 26 | v := get10p() 27 | x = v.data[5] 28 | } 29 | } 30 | 31 | //go:noinline 32 | func BenchmarkValue10Out(b *testing.B) { 33 | for i := 0; i < b.N; i++ { 34 | v := get10v() 35 | x = v.data[5] 36 | } 37 | } 38 | 39 | type v10 struct { 40 | data [10]byte 41 | } 42 | 43 | //go:noinline 44 | func readMiddle10(v v10) { 45 | x = v.data[5] 46 | } 47 | 48 | //go:noinline 49 | func readMiddle10p(v *v10) { 50 | x = v.data[5] 51 | } 52 | 53 | //go:noinline 54 | func get10p() *v10 { 55 | var v v10 56 | return &v 57 | } 58 | 59 | //go:noinline 60 | func get10v() v10 { 61 | var v v10 62 | return v 63 | } 64 | 65 | //go:noinline 66 | func BenchmarkPointer100In(b *testing.B) { 67 | var v v100 68 | for i := 0; i < b.N; i++ { 69 | readMiddle100p(&v) 70 | } 71 | } 72 | 73 | //go:noinline 74 | func BenchmarkValue100In(b *testing.B) { 75 | var v v100 76 | for i := 0; i < b.N; i++ { 77 | readMiddle100(v) 78 | } 79 | } 80 | 81 | //go:noinline 82 | func BenchmarkPointer100Out(b *testing.B) { 83 | for i := 0; i < b.N; i++ { 84 | v := get100p() 85 | x = v.data[50] 86 | } 87 | } 88 | 89 | //go:noinline 90 | func BenchmarkValue100Out(b *testing.B) { 91 | for i := 0; i < b.N; i++ { 92 | v := get100v() 93 | x = v.data[50] 94 | } 95 | } 96 | 97 | type v100 struct { 98 | data [100]byte 99 | } 100 | 101 | //go:noinline 102 | func readMiddle100(v v100) { 103 | x = v.data[50] 104 | } 105 | 106 | //go:noinline 107 | func readMiddle100p(v *v100) { 108 | x = v.data[50] 109 | } 110 | 111 | //go:noinline 112 | func get100p() *v100 { 113 | var v v100 114 | return &v 115 | } 116 | 117 | //go:noinline 118 | func get100v() v100 { 119 | var v v100 120 | return v 121 | } 122 | 123 | //go:noinline 124 | func BenchmarkPointer1_000In(b *testing.B) { 125 | var v v1_000 126 | for i := 0; i < b.N; i++ { 127 | readMiddle1_000p(&v) 128 | } 129 | } 130 | 131 | //go:noinline 132 | func BenchmarkValue1_000In(b *testing.B) { 133 | var v v1_000 134 | for i := 0; i < b.N; i++ { 135 | readMiddle1_000(v) 136 | } 137 | } 138 | 139 | //go:noinline 140 | func BenchmarkPointer1_000Out(b *testing.B) { 141 | for i := 0; i < b.N; i++ { 142 | v := get1_000p() 143 | x = v.data[500] 144 | } 145 | } 146 | 147 | //go:noinline 148 | func BenchmarkValue1_000Out(b *testing.B) { 149 | for i := 0; i < b.N; i++ { 150 | v := get1_000v() 151 | x = v.data[500] 152 | } 153 | } 154 | 155 | type v1_000 struct { 156 | data [1_000]byte 157 | } 158 | 159 | //go:noinline 160 | func readMiddle1_000(v v1_000) { 161 | x = v.data[500] 162 | } 163 | 164 | //go:noinline 165 | func readMiddle1_000p(v *v1_000) { 166 | x = v.data[500] 167 | } 168 | 169 | //go:noinline 170 | func get1_000p() *v1_000 { 171 | var v v1_000 172 | return &v 173 | } 174 | 175 | //go:noinline 176 | func get1_000v() v1_000 { 177 | var v v1_000 178 | return v 179 | } 180 | 181 | //go:noinline 182 | func BenchmarkPointer100_000In(b *testing.B) { 183 | var v v100_000 184 | for i := 0; i < b.N; i++ { 185 | readMiddle100_000p(&v) 186 | } 187 | } 188 | 189 | //go:noinline 190 | func BenchmarkValue100_000In(b *testing.B) { 191 | var v v100_000 192 | for i := 0; i < b.N; i++ { 193 | readMiddle100_000(v) 194 | } 195 | } 196 | 197 | //go:noinline 198 | func BenchmarkPointer100_000Out(b *testing.B) { 199 | for i := 0; i < b.N; i++ { 200 | v := get100_000p() 201 | x = v.data[50_000] 202 | } 203 | } 204 | 205 | //go:noinline 206 | func BenchmarkValue100_000Out(b *testing.B) { 207 | for i := 0; i < b.N; i++ { 208 | v := get100_000v() 209 | x = v.data[50_000] 210 | } 211 | } 212 | 213 | type v100_000 struct { 214 | data [100_000]byte 215 | } 216 | 217 | //go:noinline 218 | func readMiddle100_000(v v100_000) { 219 | x = v.data[50_000] 220 | } 221 | 222 | //go:noinline 223 | func readMiddle100_000p(v *v100_000) { 224 | x = v.data[50_000] 225 | } 226 | 227 | //go:noinline 228 | func get100_000p() *v100_000 { 229 | var v v100_000 230 | return &v 231 | } 232 | 233 | //go:noinline 234 | func get100_000v() v100_000 { 235 | var v v100_000 236 | return v 237 | } 238 | 239 | //go:noinline 240 | func BenchmarkPointer1_000_000In(b *testing.B) { 241 | var v v1_000_000 242 | for i := 0; i < b.N; i++ { 243 | readMiddle1_000_000p(&v) 244 | } 245 | } 246 | 247 | //go:noinline 248 | func BenchmarkValue1_000_000In(b *testing.B) { 249 | var v v1_000_000 250 | for i := 0; i < b.N; i++ { 251 | readMiddle1_000_000(v) 252 | } 253 | } 254 | 255 | //go:noinline 256 | func BenchmarkPointer1_000_000Out(b *testing.B) { 257 | for i := 0; i < b.N; i++ { 258 | v := get1_000_000p() 259 | x = v.data[500_000] 260 | } 261 | } 262 | 263 | //go:noinline 264 | func BenchmarkValue1_000_000Out(b *testing.B) { 265 | for i := 0; i < b.N; i++ { 266 | v := get1_000_000v() 267 | x = v.data[500_000] 268 | } 269 | } 270 | 271 | type v1_000_000 struct { 272 | data [1_000_000]byte 273 | } 274 | 275 | //go:noinline 276 | func readMiddle1_000_000(v v1_000_000) { 277 | x = v.data[500_000] 278 | } 279 | 280 | //go:noinline 281 | func readMiddle1_000_000p(v *v1_000_000) { 282 | x = v.data[500_000] 283 | } 284 | 285 | //go:noinline 286 | func get1_000_000p() *v1_000_000 { 287 | var v v1_000_000 288 | return &v 289 | } 290 | 291 | //go:noinline 292 | func get1_000_000v() v1_000_000 { 293 | var v v1_000_000 294 | return v 295 | } 296 | 297 | //go:noinline 298 | func BenchmarkPointer10_000_000In(b *testing.B) { 299 | var v v10_000_000 300 | for i := 0; i < b.N; i++ { 301 | readMiddle10_000_000p(&v) 302 | } 303 | } 304 | 305 | //go:noinline 306 | func BenchmarkValue10_000_000In(b *testing.B) { 307 | var v v10_000_000 308 | for i := 0; i < b.N; i++ { 309 | readMiddle10_000_000(v) 310 | } 311 | } 312 | 313 | //go:noinline 314 | func BenchmarkPointer10_000_000Out(b *testing.B) { 315 | for i := 0; i < b.N; i++ { 316 | v := get10_000_000p() 317 | x = v.data[5_000_000] 318 | } 319 | } 320 | 321 | //go:noinline 322 | func BenchmarkValue10_000_000Out(b *testing.B) { 323 | for i := 0; i < b.N; i++ { 324 | v := get10_000_000v() 325 | x = v.data[5_000_000] 326 | } 327 | } 328 | 329 | type v10_000_000 struct { 330 | data [10_000_000]byte 331 | } 332 | 333 | //go:noinline 334 | func readMiddle10_000_000(v v10_000_000) { 335 | x = v.data[5_000_000] 336 | } 337 | 338 | //go:noinline 339 | func readMiddle10_000_000p(v *v10_000_000) { 340 | x = v.data[5_000_000] 341 | } 342 | 343 | //go:noinline 344 | func get10_000_000p() *v10_000_000 { 345 | var v v10_000_000 346 | return &v 347 | } 348 | 349 | //go:noinline 350 | func get10_000_000v() v10_000_000 { 351 | var v v10_000_000 352 | return v 353 | } 354 | --------------------------------------------------------------------------------