I am trying to figure out the use ofstrings.Join method compared toregular concatenation with +=.
For this comparison, I am using both methods on os.Args as the list of strings to concatenate.
My code for the concatenating functions is:
func regular_concatenation() { var s, sep string for i := 1; i < len(os.Args); i++ { s += sep + os.Args[i] sep = " " } fmt.Println(s)}func join_concatenation() { fmt.Println(strings.Join(os.Args, " "))}
And the main function for the performance check is:
func main() { var end_1, end_2 float64 var start_1, start_2 time.Time start_1 = time.Now() for i:=0; i < 100; i++ { ex1_3_join_concatenation() } end_1 = time.Since(start_1).Seconds() start_2 = time.Now() for i:=0; i < 100; i++ { ex1_3_regular_concatenation() } end_2 = time.Since(start_2).Seconds() fmt.Println(end_1) fmt.Println(end_2)}
Problem is - when I run the code, say with 20 arguments (os.Args), I get the result that thestrings.Join method is slower than the regular concatination.
This is confusing for me, because the way I understood it - when using regular += method, it creates a new string reference each time (because strings are immutable in golang), therefore the garbage collector is supposed to run in order to collect the unused data and this wastes time.
So the question is - is strings.Join really a faster method? And if it is - what am I doing wrong in this example?
- 2Start by creating a real, independent benchmarks; poor benchmarks give poor results. The join method will have fewer allocations, and will be faster provided there aren't other confounding variables. Your
join
function also handles one more argument than the other.Mr_Pink– Mr_Pink2020-03-15 00:47:15 +00:00CommentedMar 15, 2020 at 0:47 - You have to google an info on how to benchmark go code, here's nothing to discuss, I thinkLaevus Dexter– Laevus Dexter2020-03-15 01:06:57 +00:00CommentedMar 15, 2020 at 1:06
- well, I would suggest you ask the question about what's' wrong with this benchmark. Coz your simple question has a simple answer that
strings.Join
is faster than string concatenation.Amit Upadhyay– Amit Upadhyay2020-03-15 05:31:52 +00:00CommentedMar 15, 2020 at 5:31 - 2One difference may be that you are adding os.Args[0] in the 2nd benchmark.Andrew W. Phillips– Andrew W. Phillips2020-03-15 06:51:23 +00:00CommentedMar 15, 2020 at 6:51
- Try using an array of 1000 or so elements instead of os.Args and you will see that strings.Join is faster every time.Ivan Ruski– Ivan Ruski2021-03-02 11:30:04 +00:00CommentedMar 2, 2021 at 11:30
1 Answer1
Due to various compiler optimizations string concatenationcan be quite efficient but in you case I found thatstrings.Join
is faster (see benchmarks of your code below).
In general for building up a string it is recommended to usestrings.Builder
. SeeHow to efficiently concatenate strings in go .
BTW you should be using the brilliant benchmarking facility that comes with Go. Just put these functions in a file ending with_test.go
(eg string_test.go) and rungo test -bench=.
.
func BenchmarkConcat(b *testing.B) { // 132 ns/op ss := []string {"sadsadsa", "dsadsakdas;k", "8930984"} for i := 0; i < b.N; i++ { var s, sep string for j := 0; j < len(ss); j++ { s += sep + ss[j] sep = " " } _ = s }}func BenchmarkJoin(b *testing.B) { // 56.7 ns/op ss := []string {"sadsadsa", "dsadsakdas;k", "8930984"} for i := 0; i < b.N; i++ { s := strings.Join(ss, " ") _ = s }}func BenchmarkBuilder(b *testing.B) { // 58.5 ss := []string {"sadsadsa", "dsadsakdas;k", "8930984"} for i := 0; i < b.N; i++ { var s strings.Builder // Grow builder to expected max length (maybe this // needs to be calculated dep. on your requirements) s.Grow(32) var sep string for j := 0; j < len(ss); j++ { s.WriteString(ss[j]) s.WriteString(sep) sep = " " } _ = s.String() }}
7 Comments
make([]byte, size)
andcopy
if it requires to be fastcopy
could perhaps be a little faster but you should provide the code so we can benchmark it. Personally I doubt it is much faster thanstrings.Join
and it's always better to use a know good standard library function. BTW I don't understand what you mean by "there's nothing to benchmark" unless you mean that it's so obvious which is faster that there is no point.Explore related questions
See similar questions with these tags.