Skip to content

Conversation

@1911860538
Copy link
Contributor

Below is my local test code.

encoding_test.go

package encoding
 
import (
    "strings"
    "testing"
)
 
func isASCIIUpper(c byte) bool {
    return 'A' <= c && c <= 'Z'
}
 
func jsonSnakeCase(s string) string {
    var b []byte
    for i := 0; i < len(s); i++ { // proto identifiers are always ASCII
        c := s[i]
        if isASCIIUpper(c) {
            b = append(b, '_')
            c += 'a' - 'A' // convert to lowercase
        }
        b = append(b, c)
    }
    return string(b)
}
 
func jsonSnakeCase2(s string) string {
    var builder strings.Builder
    builder.Grow(len(s))
 
    for i := 0; i < len(s); i++ { // proto identifiers are always ASCII
        c := s[i]
        if isASCIIUpper(c) {
            builder.WriteByte('_')
            c += 'a' - 'A' // convert to lowercase
        }
        builder.WriteByte(c)
    }
 
    return builder.String()
}
 
func TestJsonSnakeCase(t *testing.T) {
    tests := []struct {
        input string
    }{
        {"MyVariableName"},
        {"myVariableName"},
        {"JSONParser"},
        {"HTTPRequest"},
        {"URLShortener"},
        {"snake_case"},
        {"Mixed_snakeCase"},
        {"aB"},
        {"AB"},
        {"X"},
        {""},
        {"abc_hh2HelloWorld"},
    }
 
    for _, tt := range tests {
        result := jsonSnakeCase(tt.input)
        result3 := jsonSnakeCase2(tt.input)
        if result != result3 {
            t.Errorf("got different result")
        }
    }
}
 
var camelCase = "helloWorldGoKatos"
 
func Benchmark_jsonSnakeCase(b *testing.B) {
    b.Run("jsonSnakeCase", func(b *testing.B) {
        b.ReportAllocs()
 
        for i := 0; i < b.N; i++ {
            jsonSnakeCase(camelCase)
        }
    })
 
    b.Run("jsonSnakeCase2", func(b *testing.B) {
        b.ReportAllocs()
 
        for i := 0; i < b.N; i++ {
            jsonSnakeCase2(camelCase)
        }
    })
}
 
func jsonCamelCase(s string) string {
    var b []byte
    var wasUnderscore bool
    for i := 0; i < len(s); i++ { // proto identifiers are always ASCII
        c := s[i]
        if c != '_' {
            if wasUnderscore && isASCIILower(c) {
                c -= 'a' - 'A' // convert to uppercase
            }
            b = append(b, c)
        }
        wasUnderscore = c == '_'
    }
    return string(b)
}
 
func isASCIILower(c byte) bool {
    return 'a' <= c && c <= 'z'
}
 
func jsonCamelCase2(s string) string {
    var builder strings.Builder
    builder.Grow(len(s))
 
    wasUnderscore := false
    for i := 0; i < len(s); i++ { // proto identifiers are always ASCIIS
        c := s[i]
        if c != '_' {
            if wasUnderscore && isASCIILower(c) {
                c -= 'a' - 'A' // convert to uppercase
            }
            builder.WriteByte(c)
        }
        wasUnderscore = c == '_'
    }
 
    return builder.String()
}
 
func TestJsonCamelCase(t *testing.T) {
    tests := []struct {
        input string
    }{
        {"MyVariableName"},
        {"myVariableName"},
        {"JSONParser"},
        {"snake_case"},
        {"Mixed_snakeCase"},
        {"a_B"},
        {"A_B"},
        {"X_"},
        {"x_"},
        {"x_y"},
        {""},
        {"abc_hh2HelloWorld"},
    }
 
    for _, tt := range tests {
        result := jsonSnakeCase(tt.input)
        result3 := jsonSnakeCase2(tt.input)
        if result != result3 {
            t.Errorf("got different result")
        }
    }
}
 
var snakeCase = "hello_world_go_kratos"
 
func Benchmark_jsonCamelCase(b *testing.B) {
    b.Run("jsonCameCase", func(b *testing.B) {
        b.ReportAllocs()
 
        for i := 0; i < b.N; i++ {
            jsonCamelCase(snakeCase)
        }
    })
 
    b.Run("jsonCamelCase2", func(b *testing.B) {
        b.ReportAllocs()
 
        for i := 0; i < b.N; i++ {
            jsonCamelCase2(snakeCase)
        }
    })
}

test output

=== RUN   TestJsonSnakeCase
--- PASS: TestJsonSnakeCase (0.00s)
=== RUN   TestJsonCamelCase
--- PASS: TestJsonCamelCase (0.00s)
PASS

Process finished with the exit code 0

benchmark output

goos: darwin
goarch: amd64
pkg: testgolang/test_strings/encoding
cpu: Intel(R) Core(TM) i7-8569U CPU @ 2.80GHz
Benchmark_jsonSnakeCase
Benchmark_jsonSnakeCase/jsonSnakeCase
Benchmark_jsonSnakeCase/jsonSnakeCase-8         	11481412	        93.47 ns/op	      56 B/op	       3 allocs/op
Benchmark_jsonSnakeCase/jsonSnakeCase2
Benchmark_jsonSnakeCase/jsonSnakeCase2-8        	21125508	        50.91 ns/op	      24 B/op	       1 allocs/op
Benchmark_jsonCamelCase
Benchmark_jsonCamelCase/jsonCameCase
Benchmark_jsonCamelCase/jsonCameCase-8          	11813000	        94.79 ns/op	      56 B/op	       3 allocs/op
Benchmark_jsonCamelCase/jsonCamelCase2
Benchmark_jsonCamelCase/jsonCamelCase2-8        	22092172	        51.25 ns/op	      24 B/op	       1 allocs/op
PASS

Process finished with the exit code 0

@dosubot dosubot bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Mar 21, 2025
@dosubot dosubot bot added the LGTM label Apr 23, 2025
@tonybase tonybase merged commit 2192744 into go-kratos:main Apr 23, 2025
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

LGTM size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants