Optimizing Golang string split for performance example

Go:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package main

import (
	"strings"
	"testing"
)

var str = "asd asjhfa lsjdhalsdjhfa dhfald hfaljdh faldhfasjdhfalsdh asd alsdh alksdh alksdh alksd alkjsd fadlkj dalkjdh asdhfef afa d6a 5a85dfa s5da5d ad a6sd58ad5a8sd5f 8as5f as5 a8s5 8as6d5 8asd65f8as6d58 a5sd 8a5ds8f7 a6s5d"

func Travis() {
	words := strings.Split(str, " ")
	_ = words
}

func Travis2() {
	var words []string
	var eoc int
	for eoc != -1 {
		eoc = strings.Index(str, " ")
		if eoc == -1 {
			words = append(words, str)
			break
		}
		words = append(words, str[:eoc])
		str = str[eoc+1:]
	}
	_ = words
}

func Travis3() {
	var words []string
	var eoc int
	var cutIdx int
	for eoc != -1 {
		eoc = strings.Index(str[cutIdx:], " ")
		if eoc == -1 {
			words = append(words, str[cutIdx:])
			break
		}
		words = append(words, str[cutIdx:cutIdx+eoc])
		cutIdx += eoc + 1
	}
	_ = words
}

func BenchmarkTravis(b *testing.B) {
	b.ReportAllocs()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		for j := 0; j < 1000000; j++ {
			Travis()
		}
	}
	b.StopTimer()
}

func BenchmarkTravis2(b *testing.B) {
	b.ReportAllocs()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		for j := 0; j < 1000000; j++ {
			Travis2()
		}
	}
	b.StopTimer()
}

func BenchmarkTravis3(b *testing.B) {
	b.ReportAllocs()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		for j := 0; j < 1000000; j++ {
			Travis3()
		}
	}
	b.StopTimer()
}

output

plaintext:
1
2
3
4
// go test split_test.go -bench=. -benchmem
// BenchmarkTravis-8    	       3	 469489154 ns/op	480002720 B/op	 1000028 allocs/op
// BenchmarkTravis2-8   	      22	  48413650 ns/op	16000087 B/op	 1000000 allocs/op
// BenchmarkTravis3-8   	      22	  50924209 ns/op	16000104 B/op	 1000001 allocs/op