netpoll icon indicating copy to clipboard operation
netpoll copied to clipboard

Higher performance UnsafeStringToSlice

Open dxasu opened this issue 1 year ago • 5 comments

https://github.com/cloudwego/netpoll/blob/44a7f98a7da7ad700461433cdf4a434a0f9aeeb5/nocopy.go#L279

建议用如下函数替换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)},
	))
}

dxasu avatar Nov 22 '24 08:11 dxasu

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

joway avatar Nov 22 '24 10:11 joway

这比官方最新提供的解决方案还好吗?

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

func btsToString(bts []byte) (str string) {
	return unsafe.String(unsafe.SliceData(bts), len(bts))
}

someview avatar Feb 16 '25 06:02 someview

官方的api暂时有版本限制,在最低go版本提升至1.20之前,暂时仍使用替代方案

jayantxie avatar Feb 18 '25 02:02 jayantxie

我c,这都 2年了,还有没跟进版本的,滴滴k8s 版本过旧前车之鉴

someview avatar Feb 20 '25 07:02 someview

https://github.com/cloudwego/gopkg/tree/main/unsafex

xiaost avatar Feb 24 '25 04:02 xiaost