Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: higher performance unsafeStringToSlice #371

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from

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

Higher performance UnsafeStringToSlice
@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.

remove unused import reflect
@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.

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
3 participants