Reputation: 145
a := []byte{1, 2, 3}
// Method: 1
b := make([]byte, len(a))
copy(b, a)
// Method: 2
c := append([]byte(nil), a...)
Q: Is the method 2 more concise and efficient than method 1?
Q: Whether mode 2 and mode 1 are equivalent, both are deep copy?
thank you for your help
Upvotes: 3
Views: 5101
Reputation: 2180
To add to the accepted answer, in the example we allocate in the units of 8 bytes. We'll have slightly extended capacity for array sizes that aren't multiple of 8 bytes (or 4 bytes on a 32-bit architecture). I.e, if you try:
a := []int{1, 2, 3, 4}
// Method: 1
b := make([]int32, len(a))
copy(b, a)
// Method: 2
c := append([]int32(nil), a...)
You'll get the same length and capacity in both cases because 4 * 4B = 16B = 2 * 8B
.
I'm guessing a bit here, but it's probably performance optimisation for the smaller types - it's much faster to allocate 64 bits on 64-bit architecture rather than a smaller chunk.
A more generic example: https://go.dev/play/p/u-28butfj0L
Upvotes: 1
Reputation: 11
You can use both methods if you fix the implementation of the second method.
// Method 1
b := make([]byte, len(a))
copy(b, a)
// Method 2
c := make([]byte, 0, len(a))
c = append(c, a...)
https://go.dev/play/p/rkMmIsSaHVW
Upvotes: 1
Reputation: 22037
Method 1 is more precise - as it allocates exactly the slice size it needs & fills it.
Method 2's append will allocate a slice of capacity (depending probably on your architecture) in units of 8. So those 3 initial items will be copied to a backing array of size 8:
https://go.dev/play/p/C2nPQFflsM2
Upvotes: 9