benchmarkAppendBytes(b, 32)
}
+func benchmarkAppendStr(b *testing.B, str string) {
+ b.StopTimer()
+ x := make([]byte, 0, N)
+ b.StartTimer()
+ for i := 0; i < b.N; i++ {
+ x = x[0:0]
+ for j := 0; j < N; j++ {
+ x = append(x, str...)
+ }
+ }
+}
+
+func BenchmarkAppendStr1Byte(b *testing.B) {
+ benchmarkAppendStr(b, "1")
+}
+
+func BenchmarkAppendStr4Bytes(b *testing.B) {
+ benchmarkAppendStr(b, "1234")
+}
+
+func BenchmarkAppendStr8Bytes(b *testing.B) {
+ benchmarkAppendStr(b, "12345678")
+}
+
+func BenchmarkAppendStr16Bytes(b *testing.B) {
+ benchmarkAppendStr(b, "1234567890123456")
+}
+
+func BenchmarkAppendStr32Bytes(b *testing.B) {
+ benchmarkAppendStr(b, "12345678901234567890123456789012")
+}
+
func BenchmarkAppendSpecialCase(b *testing.B) {
b.StopTimer()
x := make([]int, 0, N)
p = ret.array+ret.len*w;
q = y.array;
w *= y.len;
- // TODO: make 16 an architecture-dependent constant.
- if(w <= 16) { // 16 empirically tested as approximate crossover on amd64.
+ if(w <= appendCrossover) {
if(p <= q || w <= p-q) // No overlap.
while(w-- > 0)
*p++ = *q++;
{
intgo m;
void *pc;
+ uintptr w;
+ uint8 *p, *q;
m = x.len+y.len;
runtime·racewriterangepc(ret.array+ret.len, y.len, 1, pc, runtime·appendstr);
}
- runtime·memmove(ret.array + ret.len, y.str, y.len);
+ // Small appends can avoid the overhead of memmove.
+ w = y.len;
+ p = ret.array+ret.len;
+ q = y.str;
+ if(w <= appendCrossover) {
+ while(w-- > 0)
+ *p++ = *q++;
+ } else {
+ runtime·memmove(p, q, w);
+ }
ret.len += y.len;
FLUSH(&ret);
}