Skip to content

Instantly share code, notes, and snippets.

@sebnyberg
Last active June 10, 2023 12:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sebnyberg/b18eab9463c3697127629ca0ee829245 to your computer and use it in GitHub Desktop.
Save sebnyberg/b18eab9463c3697127629ca0ee829245 to your computer and use it in GitHub Desktop.
Roman To Integer Benchmarks
package main_test
import (
"testing"
)
var res int
func a(x int) int {
return x
}
func BenchmarkRoman(b *testing.B) {
for _, benchCase := range []struct {
name string
f func(s string) int
}{
{"map", romanToIntMap},
{"array", romanToIntArr},
{"arraySmallLocal", romanToIntArrSmallLocal},
{"arrayLocal", romanToIntArrLocal},
{"switch", romanToIntSwitch},
} {
b.Run(benchCase.name, func(b *testing.B) {
for i := 0; i < b.N; i++ {
res = benchCase.f("MMMCMXCVIII")
a(res)
res = benchCase.f("LVIII")
a(res)
res = benchCase.f("IX")
a(res)
res = benchCase.f("MCMXCI")
a(res)
}
})
}
}
var romanMap = map[byte]int{'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
func romanToIntMap(s string) int {
var result = romanMap[s[len(s)-1]]
for i := len(s) - 2; i >= 0; i-- {
if romanMap[s[i]] < romanMap[s[i+1]] {
result -= romanMap[s[i]]
} else {
result += romanMap[s[i]]
}
}
return result
}
var romanArr = [...]int{'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
func romanToIntArr(s string) int {
var result = romanArr[s[len(s)-1]]
for i := len(s) - 2; i >= 0; i-- {
if romanArr[s[i]] < romanArr[s[i+1]] {
result -= romanArr[s[i]]
} else {
result += romanArr[s[i]]
}
}
return result
}
func romanToIntArrLocal(s string) int {
var romanArr = [256]int{'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
var result = romanArr[s[len(s)-1]]
for i := len(s) - 2; i >= 0; i-- {
if romanArr[s[i]] < romanArr[s[i+1]] {
result -= romanArr[s[i]]
} else {
result += romanArr[s[i]]
}
}
return result
}
func romanToIntArrSmallLocal(s string) int {
var romanArrSmall = [...]int{
'I' - 'C': 1,
'V' - 'C': 5,
'X' - 'C': 10,
'L' - 'C': 50,
'C' - 'C': 100,
'D' - 'C': 500,
'M' - 'C': 1000,
}
var result = romanArrSmall[s[len(s)-1]-'C']
for i := len(s) - 2; i >= 0; i-- {
if romanArrSmall[s[i]-'C'] < romanArrSmall[s[i+1]-'C'] {
result -= romanArrSmall[s[i]-'C']
} else {
result += romanArrSmall[s[i]-'C']
}
}
return result
}
func romanToIntSwitch(s string) int {
var result = getVal(s[len(s)-1])
for i := len(s) - 2; i >= 0; i-- {
if getVal(s[i]) < getVal(s[i+1]) {
result -= getVal(s[i])
} else {
result += getVal(s[i])
}
}
return result
}
func getVal(s byte) int {
switch s {
case 'I':
return 1
case 'V':
return 5
case 'X':
return 10
case 'L':
return 50
case 'C':
return 100
case 'D':
return 500
case 'M':
return 1000
default:
return 0
}
}
@sebnyberg
Copy link
Author

sebnyberg commented Jun 8, 2023

$ go test -run=None -bench=./... -benchmem -cpuprofile=cpu.pprof .
goos: linux
goarch: amd64
pkg: github.com/sebnyberg/leetcode/tmp
cpu: Intel(R) Core(TM) i5-8500 CPU @ 3.00GHz
BenchmarkRoman/map-6                   1289235               921.8 ns/op             0 B/op          0 allocs/op
BenchmarkRoman/array-6                45800854                26.06 ns/op            0 B/op          0 allocs/op
BenchmarkRoman/arraySmallLocal-6      24761743                48.27 ns/op            0 B/op          0 allocs/op
BenchmarkRoman/arrayLocal-6            8292146               802.3 ns/op             0 B/op          0 allocs/op
BenchmarkRoman/switch-6               10335658               116.2 ns/op             0 B/op          0 allocs/op
PASS
ok      github.com/sebnyberg/leetcode/tmp       13.440s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment