cloudwego / netpoll

A high-performance non-blocking I/O networking framework focusing on RPC scenarios.
Apache License 2.0
4.07k stars 470 forks source link

perf: higher performance unsafeStringToSlice #371

Open dxasu opened 1 week ago

dxasu commented 1 week ago

Higher performance UnsafeStringToSlice

What type of PR is this?

perf

Check the PR title.

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

en: higher performance unsafeStringToSlice

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

Fixes #370

xiaost commented 1 week ago

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

joway commented 4 days ago

@xiaost https://github.com/cloudwego/netpoll/issues/370 it just reduce the MOVQ instruction times. the assumption is sliceHeader and stringHeader should not change in the future.

xiaost commented 4 days ago

@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 commented 4 days ago
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 commented 3 days ago

@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 commented 3 days ago

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