Last active
March 9, 2019 13:10
-
-
Save maxclaus/ed0cda578edc449748d99ee28c586dec to your computer and use it in GitHub Desktop.
Performance over different approaches to get a mask format from a HTTP status code (e.g. 201=2xx, 204=2xx, 405=4xx, 500=5xx)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
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.