Last active
August 13, 2021 08:08
-
-
Save hugefiver/810b42f5449f300b35301d90ae520a43 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"math/rand" | |
"testing" | |
) | |
const Max = 100_0000 | |
const Offset = 100 | |
func BenchmarkSliceCopySame(b *testing.B) { | |
a := []int{} | |
for i := 0; i < Max; i++ { | |
a = append(a, rand.Int()) | |
} | |
b.ResetTimer() | |
for i := 0; i < b.N; i++ { | |
copy(a, a[:Max]) | |
} | |
} | |
func BenchmarkSliceCopy(b *testing.B) { | |
a := []int{} | |
c := make([]int, Max) | |
for i := 0; i < Max; i++ { | |
a = append(a, rand.Int()) | |
} | |
b.ResetTimer() | |
for i := 0; i < b.N; i++ { | |
copy(c, a[:Max]) | |
} | |
} | |
func BenchmarkSliceCopySameOffset(b *testing.B) { | |
a := []int{} | |
for i := 0; i < Max; i++ { | |
a = append(a, rand.Int()) | |
} | |
b.ResetTimer() | |
for i := 0; i < b.N; i++ { | |
copy(a[Offset:], a[:Max-Offset]) | |
} | |
} | |
func BenchmarkSliceCopyOffset(b *testing.B) { | |
a := []int{} | |
c := make([]int, Max) | |
for i := 0; i < Max; i++ { | |
a = append(a, rand.Int()) | |
} | |
b.ResetTimer() | |
for i := 0; i < b.N; i++ { | |
copy(c[Offset:], a[:Max-Offset]) | |
} | |
} | |
func BenchmarkSliceCopySameAppend(b *testing.B) { | |
a := []int{} | |
for i := 0; i < Max; i++ { | |
a = append(a, rand.Int()) | |
} | |
b.ResetTimer() | |
for i := 0; i < b.N; i++ { | |
a = append(a[:0], a[:Max]...) | |
} | |
} | |
func BenchmarkSliceCopyAppend(b *testing.B) { | |
a := []int{} | |
c := make([]int, Max) | |
for i := 0; i < Max; i++ { | |
a = append(a, rand.Int()) | |
} | |
b.ResetTimer() | |
for i := 0; i < b.N; i++ { | |
a = append(c[:0], a[:Max]...) | |
} | |
} | |
func BenchmarkSliceCopySameAppendOffset(b *testing.B) { | |
a := []int{} | |
for i := 0; i < Max; i++ { | |
a = append(a, rand.Int()) | |
} | |
b.ResetTimer() | |
for i := 0; i < b.N; i++ { | |
a = append(a[:Offset], a[:Max-Offset]...) | |
} | |
} | |
func BenchmarkSliceCopyAppendOffset(b *testing.B) { | |
a := []int{} | |
c := make([]int, Max) | |
for i := 0; i < Max; i++ { | |
a = append(a, rand.Int()) | |
} | |
b.ResetTimer() | |
for i := 0; i < b.N; i++ { | |
a = append(c[:Offset], a[:Max-Offset]...) | |
} | |
} |
Author
hugefiver
commented
Aug 13, 2021
func BenchmarkSliceCopySame(b *testing.B) {
a := make([]struct{}, Max)
b.ResetTimer()
for i := 0; i < b.N; i++ {
copy(a, a[:Max])
}
}
func BenchmarkSliceCopy(b *testing.B) {
a := make([]struct{}, Max)
c := make([]struct{}, Max)
b.ResetTimer()
for i := 0; i < b.N; i++ {
copy(c, a[:Max])
}
}
func BenchmarkSliceCopySameOffset(b *testing.B) {
a := make([]struct{}, Max)
b.ResetTimer()
for i := 0; i < b.N; i++ {
copy(a[Offset:], a[:Max-Offset])
}
}
func BenchmarkSliceCopyOffset(b *testing.B) {
a := make([]struct{}, Max)
c := make([]struct{}, Max)
b.ResetTimer()
for i := 0; i < b.N; i++ {
copy(c[Offset:], a[:Max-Offset])
}
}
func BenchmarkSliceCopySameAppend(b *testing.B) {
a := make([]struct{}, Max)
b.ResetTimer()
for i := 0; i < b.N; i++ {
a = append(a[:0], a[:Max]...)
}
}
func BenchmarkSliceCopyAppend(b *testing.B) {
a := make([]struct{}, Max)
c := make([]struct{}, Max)
b.ResetTimer()
for i := 0; i < b.N; i++ {
a = append(c[:0], a[:Max]...)
}
}
func BenchmarkSliceCopySameAppendOffset(b *testing.B) {
a := make([]struct{}, Max)
b.ResetTimer()
for i := 0; i < b.N; i++ {
a = append(a[:Offset], a[:Max-Offset]...)
}
}
func BenchmarkSliceCopyAppendOffset(b *testing.B) {
a := make([]struct{}, Max)
c := make([]struct{}, Max)
b.ResetTimer()
for i := 0; i < b.N; i++ {
a = append(c[:Offset], a[:Max-Offset]...)
}
}
See source
// slicecopy is used to copy from a string or slice of pointerless elements into a slice.
func slicecopy(toPtr unsafe.Pointer, toLen int, fromPtr unsafe.Pointer, fromLen int, width uintptr) int {
if fromLen == 0 || toLen == 0 {
return 0
}
n := fromLen
if toLen < n {
n = toLen
}
if width == 0 {
return n
}
size := uintptr(n) * width
if raceenabled {
callerpc := getcallerpc()
pc := abi.FuncPCABIInternal(slicecopy)
racereadrangepc(fromPtr, size, callerpc, pc)
racewriterangepc(toPtr, size, callerpc, pc)
}
if msanenabled {
msanread(fromPtr, size)
msanwrite(toPtr, size)
}
if size == 1 { // common case worth about 2x to do here
// TODO: is this still worth it with new memmove impl?
*(*byte)(toPtr) = *(*byte)(fromPtr) // known to be a byte pointer
} else {
memmove(toPtr, fromPtr, size)
}
return n
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment