Skip to content

Conversation

@ganigeorgiev
Copy link
Contributor

Currently ToString/ToStringE always attempts to perform pointer dereference before the type checks which adds significant overhead when casting non-pointer values (for pointers it is also not very optimal because the reflection of errorType and fmtStringerType would be evaluated on every ToString/ToStringE call).

This PR:

  • moves the pointer check in the default clause and calls ToStringE with its underlying value
  • updates the existing tests with equivalent checks for pointers

Below are some basic benchmark results from my local environment (the best from 3 consequent runs):

  1. Plain value

    func BenchmarkToString(b *testing.B) {
        for range b.N {
            cast.ToString("test")
        }
    }
    // Old:
    BenchmarkToString-4     19877439          60.69 ns/op
    
    // New:
    BenchmarkToString-4     282848110         4.364 ns/op
    
  2. Pointer

    func BenchmarkToString(b *testing.B) {
        v := "test"
        for range b.N {
            cast.ToString(&v)
        }
    }
    // Old:
    BenchmarkToString-4      4797831         287.2 ns/op
    
    // New:
    BenchmarkToString-4     10021204         216.1 ns/op
    
@CLAassistant
Copy link

CLAassistant commented May 5, 2025

CLA assistant check
All committers have signed the CLA.

Copy link
Collaborator

@sagikazarmark sagikazarmark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks

@sagikazarmark sagikazarmark merged commit 9354fd3 into spf13:master May 29, 2025
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

3 participants