An efficient way to compare strings in Go
| Reading Time : 3 minutes | #backenddevelopment #Go
One of the most overlooked operations is comparing two strings and this might not cause system overhead but definitely, it is a good practice to write an efficient code where possible. These small dividends definitely pay at the end when the application is under real stress in production.
Note: I am amateur in Go if you are an experienced professional in Go and find anything wrong here don’t be annoyed. If you could point the mistake I will correct those accordingly.
One of the often used string comparisons is
strings.ToLower(stringA) == strings.ToLower(stringB)
but this way of comparing takes a lot of time per operation and the reason is, In Go, a string is an immutable sequence of runes. rune in Go is an integer value represents code point
The more detailed and sensible explanation is given by Rob Pike in blog: https://blog.golang.org/strings Its a very nice bedtime read which gives a recap of basics of strings in programming languages.
Here ToLower a standard function in strings package which when used traverse through the entire string converts it to a lower case and returns a new string cause strings in Go is immutable which means strings.ToLower allocates new memory spaces for these two strings.
sample code:
func CompareStringsInCrudeWay(stringA, stringB string) (bool, error) {
if strings.ToLower(stringA) == strings.ToLower(stringB) {
return true, nil
} else {
return false, nil
}
}
Benchmark:
Input:
stringA = "rakesh123456789mothukuri123456789"
stringB = "ramesh123456789mothukuri123456789"
BenchmarkCompare-8 8304722 151 ns/op 0 B/op 0 allocs/op
If we notice in earlier benchmark figures this operation takes 151 nanoseconds
per operation. But is this too much we need to talk about? No, but if there is a simple change to way strings are compared and we could get this down to 30 nanoseconds why not?
Optimization
To optimize we could find a way instead traverse through runes of each string, compare each character in the string, if rune doesn’t match we would convert rune to lowercase and compare again and if they still don’t match we break the loop and break the loop and return strings are not same. This process will save operation time spent comparing string.
Pseudocode
func Compare(stringA, stringB string) bool {
for i := 0; i < len(stringA); i++ {
if stringA[i] == stringB[i] {
continue
}
if unicode.ToLower(stringA[i]) != unicode.ToLower(stringB[i]) {
return false
}
}
return true
}
But this has more logic here to remember and implement every time we compare string only if there is an easy way to do. Go strings package has a method which performs in this fashion which is strings.EqualFold
sample code using EqualFold
func CompareStringsInEfficientWay(stringA, stringB string) (bool, error) {
if strings.EqualFold(stringA, stringB) {
return true, nil
} else {
return false, nil
}
}
Benchmark:
Input:
stringA = "rakesh123456789mothukuri123456789"
stringB = "ramesh123456789mothukuri123456789"
BenchmarkCompare-8 76842292 17.1 ns/op 0 B/op 0 allocs/op
Now, it took 17 nanoseconds per operation, These small wins over a period of time will definitely payback, not only they pay back it also helps promote an efficient way of writing code.
This is the end of the blog if you think there is a more efficient way of comparing string in Go please drop me a message I will attribute you and amend the content.
powerctl is a little weekend project I put together to provide a simple tool for managing power states on Linux. I had previously put my laptop into suspend with a basic “echo mem | doas tee /sys/power/state”, but this leaves a lot to be desired. I have to u…
via Drew DeVault's blog August 28, 2022Links to exhibits from the Microsoft anti-trust case, with a bit of info on each link. Projection of PC marketshare Share of new browser users Share of the browser market, grouped by major ISP, 3 month moving average Share of the browser market, grouped by ma…
via danluu.com August 24, 2022Hi all! This month I’ve been pondering offline-first apps. The online aspect of modern apps is an important feature for many use-cases: it enables collaboration between multiple people and seamless transition between devices (e.g. I often switch between my pe…
via emersion August 14, 2022Generated by openring