Skip to content

Instantly share code, notes, and snippets.

@sebnyberg
Last active June 10, 2023 12:52
Show Gist options
  • Select an option

  • Save sebnyberg/b18eab9463c3697127629ca0ee829245 to your computer and use it in GitHub Desktop.

Select an option

Save sebnyberg/b18eab9463c3697127629ca0ee829245 to your computer and use it in GitHub Desktop.

Revisions

  1. sebnyberg revised this gist Jun 10, 2023. 1 changed file with 45 additions and 51 deletions.
    96 changes: 45 additions & 51 deletions tmp_test.go
    Original file line number Diff line number Diff line change
    @@ -1,58 +1,39 @@
    package tmp
    package main_test

    import (
    "math/rand"
    "testing"
    )

    func randRoman() string {
    letters := "MDCCLXXVII"
    bm := 1 + rand.Intn((1<<(len(letters)))-1)
    var res []byte
    for i := range letters {
    if bm&(1<<i) > 0 {
    res = append(res, letters[i])
    }
    }
    return string(res)
    }

    var res int

    func a(x int) int {
    return x
    }

    func BenchmarkRoman(b *testing.B) {
    const n = 1e5
    nums := make([]string, n)
    for i := range nums {
    nums[i] = randRoman()
    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)
    }
    })
    }
    b.Run("map", func(b *testing.B) {
    for i := 0; i < b.N; i++ {
    res = romanToIntMap(nums[i%n])
    a(res)
    }
    })
    b.Run("array", func(b *testing.B) {
    for i := 0; i < b.N; i++ {
    res = romanToIntArr(nums[i%n])
    a(res)
    }
    })
    b.Run("arraySmall", func(b *testing.B) {
    for i := 0; i < b.N; i++ {
    res = romanToIntArrSmall(nums[i%n])
    a(res)
    }
    })
    b.Run("switch", func(b *testing.B) {
    for i := 0; i < b.N; i++ {
    res = romanToIntSwitch(nums[i%n])
    a(res)
    }
    })
    }

    var romanMap = map[byte]int{'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
    @@ -85,17 +66,30 @@ func romanToIntArr(s string) int {
    return result
    }

    var romanArrSmall = [...]int{
    'I' - 'C': 1,
    'V' - 'C': 5,
    'X' - 'C': 10,
    'L' - 'C': 50,
    'C' - 'C': 100,
    'D' - 'C': 500,
    'M' - 'C': 1000,
    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 romanToIntArrSmall(s string) int {
    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-- {
  2. sebnyberg revised this gist Jun 8, 2023. 1 changed file with 30 additions and 1 deletion.
    31 changes: 30 additions & 1 deletion tmp_test.go
    Original file line number Diff line number Diff line change
    @@ -41,6 +41,12 @@ func BenchmarkRoman(b *testing.B) {
    a(res)
    }
    })
    b.Run("arraySmall", func(b *testing.B) {
    for i := 0; i < b.N; i++ {
    res = romanToIntArrSmall(nums[i%n])
    a(res)
    }
    })
    b.Run("switch", func(b *testing.B) {
    for i := 0; i < b.N; i++ {
    res = romanToIntSwitch(nums[i%n])
    @@ -79,6 +85,29 @@ func romanToIntArr(s string) int {
    return result
    }

    var romanArrSmall = [...]int{
    'I' - 'C': 1,
    'V' - 'C': 5,
    'X' - 'C': 10,
    'L' - 'C': 50,
    'C' - 'C': 100,
    'D' - 'C': 500,
    'M' - 'C': 1000,
    }

    func romanToIntArrSmall(s string) int {
    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])

    @@ -111,4 +140,4 @@ func getVal(s byte) int {
    default:
    return 0
    }
    }
    }
  3. sebnyberg revised this gist Jun 8, 2023. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions tmp_test.go
    Original file line number Diff line number Diff line change
    @@ -41,7 +41,7 @@ func BenchmarkRoman(b *testing.B) {
    a(res)
    }
    })
    b.Run("func", func(b *testing.B) {
    b.Run("switch", func(b *testing.B) {
    for i := 0; i < b.N; i++ {
    res = romanToIntSwitch(nums[i%n])
    a(res)
    @@ -111,4 +111,4 @@ func getVal(s byte) int {
    default:
    return 0
    }
    }
    }
  4. sebnyberg revised this gist Jun 8, 2023. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions tmp_test.go
    Original file line number Diff line number Diff line change
    @@ -43,7 +43,7 @@ func BenchmarkRoman(b *testing.B) {
    })
    b.Run("func", func(b *testing.B) {
    for i := 0; i < b.N; i++ {
    res = romanToIntFunc(nums[i%n])
    res = romanToIntSwitch(nums[i%n])
    a(res)
    }
    })
    @@ -79,7 +79,7 @@ func romanToIntArr(s string) int {
    return result
    }

    func romanToIntFunc(s string) int {
    func romanToIntSwitch(s string) int {
    var result = getVal(s[len(s)-1])

    for i := len(s) - 2; i >= 0; i-- {
    @@ -111,4 +111,4 @@ func getVal(s byte) int {
    default:
    return 0
    }
    }
    }
  5. sebnyberg revised this gist Jun 8, 2023. 1 changed file with 8 additions and 6 deletions.
    14 changes: 8 additions & 6 deletions tmp_test.go
    Original file line number Diff line number Diff line change
    @@ -49,8 +49,9 @@ func BenchmarkRoman(b *testing.B) {
    })
    }

    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 romanMap = map[byte]int{'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
    var result = romanMap[s[len(s)-1]]

    for i := len(s) - 2; i >= 0; i-- {
    @@ -63,15 +64,16 @@ func romanToIntMap(s string) int {
    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 romanMap = [...]int{'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
    var result = romanMap[s[len(s)-1]]
    var result = romanArr[s[len(s)-1]]

    for i := len(s) - 2; i >= 0; i-- {
    if romanMap[s[i]] < romanMap[s[i+1]] {
    result -= romanMap[s[i]]
    if romanArr[s[i]] < romanArr[s[i+1]] {
    result -= romanArr[s[i]]
    } else {
    result += romanMap[s[i]]
    result += romanArr[s[i]]
    }
    }
    return result
  6. sebnyberg created this gist Jun 8, 2023.
    112 changes: 112 additions & 0 deletions tmp_test.go
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,112 @@
    package tmp

    import (
    "math/rand"
    "testing"
    )

    func randRoman() string {
    letters := "MDCCLXXVII"
    bm := 1 + rand.Intn((1<<(len(letters)))-1)
    var res []byte
    for i := range letters {
    if bm&(1<<i) > 0 {
    res = append(res, letters[i])
    }
    }
    return string(res)
    }

    var res int

    func a(x int) int {
    return x
    }

    func BenchmarkRoman(b *testing.B) {
    const n = 1e5
    nums := make([]string, n)
    for i := range nums {
    nums[i] = randRoman()
    }
    b.Run("map", func(b *testing.B) {
    for i := 0; i < b.N; i++ {
    res = romanToIntMap(nums[i%n])
    a(res)
    }
    })
    b.Run("array", func(b *testing.B) {
    for i := 0; i < b.N; i++ {
    res = romanToIntArr(nums[i%n])
    a(res)
    }
    })
    b.Run("func", func(b *testing.B) {
    for i := 0; i < b.N; i++ {
    res = romanToIntFunc(nums[i%n])
    a(res)
    }
    })
    }

    func romanToIntMap(s string) int {
    var romanMap = map[byte]int{'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
    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
    }

    func romanToIntArr(s string) int {
    var romanMap = [...]int{'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
    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
    }

    func romanToIntFunc(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
    }
    }