Performance over different approaches to get a mask format from a HTTP status code (e.g. 201=2xx, 204=2xx, 405=4xx, 500=5xx)
package util_test | |
import ( | |
"fmt" | |
"math" | |
"regexp" | |
"strconv" | |
"testing" | |
) | |
var re = regexp.MustCompile(`\d{2}$`) | |
// Get a masked value from a http status code (e.g. 201=2xx, 204=2xx, 405=4xx, 500=5xx) | |
func BenchmarkStatusBucket(b *testing.B) { | |
statusCode := 201 | |
b.Run("if-statements", func(b *testing.B) { | |
for i := 0; i < b.N; i++ { | |
s := getStatusIfStatemets(statusCode) | |
_ = s | |
} | |
}) | |
b.Run("Itoa+concat", func(b *testing.B) { | |
for i := 0; i < b.N; i++ { | |
s := getStatusItoaWithConcat(statusCode) | |
_ = s | |
} | |
}) | |
b.Run("Itoa+[]byte", func(b *testing.B) { | |
for i := 0; i < b.N; i++ { | |
s := getStatusItoaWithByteArray(statusCode) | |
_ = s | |
} | |
}) | |
b.Run("Itoa+Sprintf", func(b *testing.B) { | |
for i := 0; i < b.N; i++ { | |
s := getStatusItoaWithSprintf(statusCode) | |
_ = s | |
} | |
}) | |
b.Run("regex+concat", func(b *testing.B) { | |
for i := 0; i < b.N; i++ { | |
s := getStatusRegexWithConcat(statusCode) | |
_ = s | |
} | |
}) | |
b.Run("math+Sprintf", func(b *testing.B) { | |
for i := 0; i < b.N; i++ { | |
s := getStatusMathWithSprintf(statusCode) | |
_ = s | |
} | |
}) | |
} | |
var ( | |
status1xx = "1xx" | |
status2xx = "2xx" | |
status3xx = "3xx" | |
status4xx = "4xx" | |
status5xx = "5xx" | |
) | |
func getStatusIfStatemets(statusCode int) string { | |
if statusCode >= 100 && statusCode < 200 { | |
return status1xx | |
} else if statusCode < 300 { | |
return status2xx | |
} else if statusCode < 400 { | |
return status3xx | |
} else if statusCode < 500 { | |
return status4xx | |
} | |
return status5xx | |
} | |
func getStatusItoaWithConcat(statusCode int) string { | |
return string(strconv.Itoa(statusCode)[0]) + "xx" | |
} | |
func getStatusItoaWithByteArray(statusCode int) string { | |
b := make([]byte, 3) | |
b[0] = strconv.Itoa(statusCode)[0] | |
b[1] = 'x' | |
b[2] = 'x' | |
return string(b[:]) | |
} | |
func getStatusItoaWithSprintf(statusCode int) string { | |
return fmt.Sprintf("%dxx", strconv.Itoa(statusCode)[0]) | |
} | |
func getStatusRegexWithConcat(statusCode int) string { | |
return re.ReplaceAllString(strconv.FormatInt(int64(statusCode), 10), `XX`) | |
} | |
func getStatusMathWithSprintf(statusCode int) string { | |
return fmt.Sprintf("%.0fxx", math.Floor(float64(statusCode/100))) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
go version go1.12 darwin/amd64
Benchmark test
Memory profiling alloc_space
This report shows the if statement is the fastest and with less allocations and the regex approach is the opposite of that.