Entry tags:
Go: what is faster, buf.WriteString("...") or str += "..."?
More or less since I started programming in Go, I have wanted to know which method I should use for collecting strings: (a) use a
The result was more clear-cut than I had expected:
The
bytes.Buffer and WriteString(), or (b) just "add" together a string with +=. The convenience of the latter is appealing, but how would that be performance-wise? So I finally checked it.
package main
import (
"bytes"
"fmt"
"os"
"time"
)
var startT time.Time
func main() {
for reps := 10000; reps <= 100000; reps += 10000 {
fmt.Printf("\nreps: %d\n", reps)
snippet := os.Args[1]
startT = time.Now()
buf1 := bytes.NewBufferString("")
for i := 0; i < reps; i++ {
buf1.WriteString(snippet)
}
seconds1 :=
float64(time.Now().Sub(startT)) / float64(time.Second)
len1 := buf1.Len()
fmt.Printf("last of %d: %s; %g s\n", len1,
buf1.Bytes()[len1-10:len1-1], seconds1)
startT = time.Now()
buf2 := ""
for i := 0; i < reps; i++ {
buf2 += snippet
}
seconds2 :=
float64(time.Now().Sub(startT)) / float64(time.Second)
len2 := len(buf2)
fmt.Printf("last of %d: %s; %g s\n", len2,
buf2[len2-10:len2-1], seconds2)
}
}
The result was more clear-cut than I had expected:
$ ./strcatz fldsjbcsldfbcdkhasfacde reps: 10000 last of 230000: dkhasfacd; 0.001061327 s last of 230000: dkhasfacd; 0.501937235 s reps: 20000 last of 460000: dkhasfacd; 0.001232219 s last of 460000: dkhasfacd; 2.42185104 s reps: 30000 last of 690000: dkhasfacd; 0.00211587 s last of 690000: dkhasfacd; 6.120059 s reps: 40000 last of 920000: dkhasfacd; 0.002452257 s last of 920000: dkhasfacd; 13.718863728 s reps: 50000 last of 1150000: dkhasfacd; 0.0048127 s last of 1150000: dkhasfacd; 18.529621865 s reps: 60000 last of 1380000: dkhasfacd; 0.004334798 s last of 1380000: dkhasfacd; 24.74539053 s reps: 70000 last of 1610000: dkhasfacd; 0.005095205 s last of 1610000: dkhasfacd; 32.982584273 s reps: 80000 last of 1840000: dkhasfacd; 0.009039379 s last of 1840000: dkhasfacd; 44.176404262 s reps: 90000 last of 2070000: dkhasfacd; 0.008148565 s last of 2070000: dkhasfacd; 53.003958242 s reps: 100000 last of 2300000: dkhasfacd; 0.008536743 s last of 2300000: dkhasfacd; 67.390456565 s
The
+= method is not only slower to begin with, but also goes up more than linear, which is not quite surprising. I do find it surprising, though, that the difference is so large, in the order of 10000. So, I guess, that question is answered: In a place where performance matters at all, don't use += for repeated string concatenation.