package main
import "strings"
import "unsafe"
import "testing"
// a copu of the string.Join function
func joinx(a []string, sep string) string {
switch len(a) {
case 0:
return ""
case 1:
return a[0]
case 2:
// Special case for common small values.
// Remove if golang.org/issue/6714 is fixed
return a[0] + sep + a[1]
case 3:
// Special case for common small values.
// Remove if golang.org/issue/6714 is fixed
return a[0] + sep + a[1] + sep + a[2]
}
n := len(sep) * (len(a) - 1)
for i := 0; i < len(a); i++ {
n += len(a[i])
}
b := make([]byte, n)
bp := copy(b, a[0])
for _, s := range a[1:] {
bp += copy(b[bp:], sep)
bp += copy(b[bp:], s)
}
return string(b)
}
func joiny(a []string, sep string) string {
switch len(a) {
case 0:
return ""
case 1:
return a[0]
case 2:
// Special case for common small values.
// Remove if golang.org/issue/6714 is fixed
return a[0] + sep + a[1]
case 3:
// Special case for common small values.
// Remove if golang.org/issue/6714 is fixed
return a[0] + sep + a[1] + sep + a[2]
}
n := len(sep) * (len(a) - 1)
for i := 0; i < len(a); i++ {
n += len(a[i])
}
var b strings.Builder
b.Grow(n)
b.WriteString(a[0])
for _, s := range a[1:] {
b.WriteString(sep)
b.WriteString(s)
}
return b.String()
}
func joinz(a []string, sep string) string {
switch len(a) {
case 0:
return ""
case 1:
return a[0]
case 2:
// Special case for common small values.
// Remove if golang.org/issue/6714 is fixed
return a[0] + sep + a[1]
case 3:
// Special case for common small values.
// Remove if golang.org/issue/6714 is fixed
return a[0] + sep + a[1] + sep + a[2]
}
n := len(sep) * (len(a) - 1)
for i := 0; i < len(a); i++ {
n += len(a[i])
}
b := make([]byte, n)
bp := copy(b, a[0])
for _, s := range a[1:] {
bp += copy(b[bp:], sep)
bp += copy(b[bp:], s)
}
return *(*string)(unsafe.Pointer(&b))
}
var words = []string{"abcdefghijklmn", "opqrstuvwxyz", "abcdefghijklmn", "opqrstuvwxyz", "abcdefghijklmn", "opqrstuvwxyz", "abcdefghijklmn", "opqrstuvwxyz", "abcdefghijklmn", "opqrstuvwxyz", }
var x, y, z string
func Benchmark_x(b *testing.B) {
for i := 0; i < b.N; i++ {
x = joinx(words, ",")
}
}
func Benchmark_y(b *testing.B) {
for i := 0; i < b.N; i++ {
y = joiny(words, ",")
}
}
func Benchmark_z(b *testing.B) {
for i := 0; i < b.N; i++ {
y = joinz(words, ",")
}
}
Benchmark_x-4 3000000 454 ns/op 288 B/op 2 allocs/op
Benchmark_y-4 3000000 530 ns/op 144 B/op 1 allocs/op
Benchmark_z-4 5000000 335 ns/op 144 B/op 1 allocs/op
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Good observation: I should not have said "always:" because when the array is short or the strings are short then you are testing the wrapper code and not the string-joining code. That may fall either way.
name old time/op new time/op delta
_x 320ns ± 0% 341ns ± 1% +6.62% (p=0.000 n=9+10)
_y 409ns ± 1% 268ns ± 1% -34.31% (p=0.000 n=10+10)
_z 251ns ± 1% 264ns ± 0% +4.88% (p=0.000 n=10+9)
I made a test on my local machine. If the copyCheck method is modified as the following one.
The efficiencies of fy and fz become almost the same.
name old time/op new time/op delta
_x 320ns ± 0% 341ns ± 1% +6.62% (p=0.000 n=9+10)
_y 409ns ± 1% 268ns ± 1% -34.31% (p=0.000 n=10+10)
_z 251ns ± 1% 264ns ± 0% +4.88% (p=0.000 n=10+9)
However, the benchmark results on my computer often some illogical.
So can anyone help me verify the above result?func (b *Builder) copyCheck() {if b.addr != b {if b.addr != nil {panic("strings: illegal use of non-zero Builder copied by value")}// This hack works around a failing of Go's escape analysis// that was causing b to escape and be heap allocated.// See issue 23382.// TODO: once issue 7921 is fixed, this should be reverted to// just "b.addr = b".b.addr = (*Builder)(noescape(unsafe.Pointer(b)))}}
Il giorno martedì 19 giugno 2018 17:39:54 UTC+2, T L ha scritto:
I made a test on my local machine. If the copyCheck method is modified as the following one.
The efficiencies of fy and fz become almost the same.
name old time/op new time/op delta
_x 320ns ± 0% 341ns ± 1% +6.62% (p=0.000 n=9+10)
_y 409ns ± 1% 268ns ± 1% -34.31% (p=0.000 n=10+10)
_z 251ns ± 1% 264ns ± 0% +4.88% (p=0.000 n=10+9)
However, the benchmark results on my computer often some illogical.I had the same issue with similar code. Maybe the cause is the same?
I made a test on my local machine. If the copyCheck method is modified as the following one.
The efficiencies of fy and fz become almost the same.
name old time/op new time/op delta
_x 320ns ± 0% 341ns ± 1% +6.62% (p=0.000 n=9+10)
_y 409ns ± 1% 268ns ± 1% -34.31% (p=0.000 n=10+10)
_z 251ns ± 1% 264ns ± 0% +4.88% (p=0.000 n=10+9)
However, the benchmark results on my computer often some illogical.
So can anyone help me verify the above result?