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

Higher performance UnsafeStringToSlice #370

Open
dxasu opened this issue Nov 22, 2024 · 1 comment · May be fixed by #371
Open

Higher performance UnsafeStringToSlice #370

dxasu opened this issue Nov 22, 2024 · 1 comment · May be fixed by #371

Comments

@dxasu
Copy link
Contributor

dxasu commented Nov 22, 2024

func unsafeStringToSlice(s string) (b []byte) {

建议用如下函数替换UnsafeStringToSlice,经过benchmark测试,性能提高约30%左右,代码也更优雅

func UnsafeStringToSlice2(s string) []byte {
	return *(*[]byte)(unsafe.Pointer(
		&struct {
			string
			int
		}{s, len(s)},
	))
}

### 测试详情

go test -bench . -benchmem
goos: darwin
goarch: arm64
pkg: gitlab-vywrajy.zd100.net/slice/service
BenchmarkToSlice/UnsafeStringToSlice-8 737677520 1.542 ns/op 0 B/op 0 allocs/op
BenchmarkToSlice/UnsafeStringToSlice2-8 1000000000 1.188 ns/op 0 B/op 0 allocs/op
PASS
ok gitlab-vywrajy.zd100.net/slice/service 2.928s

### 相关测试代码

package service

import (
	"reflect"
	"testing"
	"unsafe"
)

func BenchmarkToSlice(b *testing.B) {
	a := "hello world"
	var bs []byte
	b.Run("UnsafeStringToSlice", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			bs = UnsafeStringToSlice(a)
		}
	})
	b.Run("UnsafeStringToSlice2", func(b *testing.B) {
		for i := 0; i < b.N; i++ {
			bs = UnsafeStringToSlice2(a)
		}
	})

	_ = bs
}



func UnsafeStringToSlice(s string) (b []byte) {
	p := unsafe.Pointer((*reflect.StringHeader)(unsafe.Pointer(&s)).Data)
	hdr := (*reflect.SliceHeader)(unsafe.Pointer(&b))
	hdr.Data = uintptr(p)
	hdr.Cap = len(s)
	hdr.Len = len(s)
	return b
}

func UnsafeStringToSlice2(s string) []byte {
	return *(*[]byte)(unsafe.Pointer(
		&struct {
			string
			int
		}{s, len(s)},
	))
}

@joway
Copy link
Member

joway commented Nov 22, 2024

@dxasu 可以提个 PR 优化下这块,看了下,就是少了几个 MOVQ 指令
image

@dxasu dxasu linked a pull request Nov 22, 2024 that will close this issue
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

2 participants