Skip to content

Conversation

dxasu
Copy link
Contributor

@dxasu dxasu commented Nov 22, 2024

Higher performance UnsafeStringToSlice

What type of PR is this?

perf

Check the PR title.

  • This PR title match the format: <type>(optional scope): <description>
  • The description of this PR title is user-oriented and clear enough for others to understand.
  • Attach the PR updating the user documentation if the current PR requires user awareness at the usage level. User docs repo

(Optional) More detailed description for this PR(en: English/zh: Chinese).

en: higher performance unsafeStringToSlice

(Optional) Which issue(s) this PR fixes:

Fixes #370

@dxasu dxasu requested review from a team as code owners November 22, 2024 10:52
@xiaost
Copy link
Contributor

xiaost commented Nov 22, 2024

Benchmark? Comparison? Also the assumption of the structure size which equals to []byte is unacceptable.

hdr.Cap = len(s)
hdr.Len = len(s)
return b
func unsafeStringToSlice(s string) []byte {
Copy link
Member

Choose a reason for hiding this comment

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

@dxasu you should remove "reflect" import path also

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@joway
Copy link
Member

joway commented Nov 25, 2024

@xiaost #370 it just reduce the MOVQ instruction times. the assumption is sliceHeader and stringHeader should not change in the future.

@xiaost
Copy link
Contributor

xiaost commented Nov 25, 2024

@joway it can be different size for string and stringheader.
reflect.StringHeader will not be changed, but it doesn't mean string can not add more fields to the end of reflect.StringHeader.

@xiaost
Copy link
Contributor

xiaost commented Nov 25, 2024

func UnsafeStringToSlice(s string) (b []byte) {
	*(*string)(unsafe.Pointer(&b)) = s
	(*reflect.SliceHeader)(unsafe.Pointer(&b)).Cap = len(s)
	return
}

try this code snippet which has better readability if we'd like to sacrifice forward compatibility for the minor optimisation.

I won't do that.

@dxasu
Copy link
Contributor Author

dxasu commented Nov 26, 2024

@xiaost
In go1.20, that reflect.StringHeader and reflect.SliceHeader are [officially deprecated]

func UnsafeStringToSlice(s string) []byte {
	return unsafe.Slice(unsafe.StringData(s), len(s))
}

@xiaost
Copy link
Contributor

xiaost commented Nov 26, 2024

@dxasu I know what you said, but I don't know what is your point.

dxasu added 2 commits July 3, 2025 16:44
Higher performance UnsafeStringToSlice
remove unused import reflect
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Higher performance UnsafeStringToSlice

4 participants