Golang: Replace vs Regexp
Hi.
So, back then when I was an intern at my last workplace, I was given a task that was related with find and match some pattern of words. What i’m going to tell you right now is a little research that I did back then and I find that it was interesting.
In Golang, there is two methods that you can use if you want to find some strings and replace it with another strings, which is:
- Regexp’s ReplaceAllString (https://golang.org/pkg/regexp/#Regexp.ReplaceAllString)
- Strings’s Replace (https://golang.org/pkg/strings/#Replace)
These two are actually the same function if you want to change some substring in a string to a another substring. For example like if you want to change the substring ‘foo’ in ‘seafood’ to ‘oof’.
But, what about the performance of both functions?
So yeah, based on Dave Cheney’s tutorial about how to create a benchmark test, I create the test to know the performance of the function ReplaceAllString and function Replace.
First, I make a file called main_test.go and add the function.
import (
"regexp"
"strings"
"testing"
)func BenchmarkReplace2(b *testing.B) {
for n := 0; n < b.N; n++ {
strings.Replace("seafood seafood", "foo", "oof", -1)
}
}func BenchmarkReplace5(b *testing.B) {
for n := 0; n < b.N; n++ {
strings.Replace("seafood seafood seafood seafood seafood",
"foo", "oof", -1)
}
}func BenchmarkReplace10(b *testing.B) {
for n := 0; n < b.N; n++ {
strings.Replace("seafood seafood seafood seafood seafood
seafood seafood seafood seafood seafood", "foo", "oof", -1)
}
}func BenchmarkRegexp2(b *testing.B) {
for n := 0; n < b.N; n++ {
r, _ := regexp.Compile("foo")
r.ReplaceAllString("seafood seafood", "oof")
}
}func BenchmarkRegexp5(b *testing.B) {
for n := 0; n < b.N; n++ {
r, _ := regexp.Compile("foo")
r.ReplaceAllString("seafood seafood seafood seafood
seafood", "oof")
}
}func BenchmarkRegexp10(b *testing.B) {
for n := 0; n < b.N; n++ {
r, _ := regexp.Compile("foo")
r.ReplaceAllString("seafood seafood seafood seafood seafood
seafood seafood seafood seafood seafood", "oof")
}
}
There are 6 functions that I created, 3 of them using Regexp and other 3 use Replace. Each of the function has the N-words of ‘seafood’ to determine the different of the process. Each word of ‘seafood’ will detected by the substring ‘foo’ and replaced by ‘oof’.
To test it out, I’m using the command go test -bench=. -benchtime=10s
, meaning that I use the test command because it is part of the testing in Golang, the -bench=.
means that all of the functions to be tested, and -benghtime=10s
means that each function is tested by the minimum of 10 seconds for the accuracy of the benchmarking.
Here is the result:
goos: darwin
goarch: amd64
pkg: benchmark
BenchmarkReplace2-4 50000000 260 ns/op
BenchmarkReplace5-4 30000000 439 ns/op
BenchmarkReplace10-4 20000000 836 ns/op
BenchmarkRegexp2-4 1000000 15149 ns/op
BenchmarkRegexp5-4 1000000 15882 ns/op
BenchmarkRegexp10-4 1000000 17538 ns/op
PASS
ok benchmark 93.629s
Do not really consider the goos and the goarch.
There are 3 atributes that just been produced by the command, the first one is the name of function, then the final value of b.N
iterations, and last is the average runtime of the function.
From the test result, we see that Replace has done more b.N
iterations than the Regexp and the Replace have faster average runtimes than the Regexp.
So, what happened?
If you lookup within the library for the Replace and Regexp’s ReplaceAllString, there is a quite different between the code (I’m not really look into it but i’m gonna update this post once I analyzed it). But it is a quite difference in the performance.
Conclusion,
So, if you want to make a program that only replace some words or strings, use the Replace function rather than the Regexp. But then again, Regexp has more capabilities if you want to match some patterns that consists not only strings.
Any comments or feedbacks will be very welcomed here. Thanks for reading!