perf: use fast unsafe bytes->string convertion#525
Conversation
tac0turtle
left a comment
There was a problem hiding this comment.
could you provide some before and after benchmarks to verify the improvements
|
Benchmark: |
|
turns out that it's significant optimization |
p0mvn
left a comment
There was a problem hiding this comment.
Hi @robert-zaremba . Great work on this optimization. I had a couple of questions. Please let me know what you think
| // UnsafeStrToBytes uses unsafe to convert string into byte array. Returned bytes | ||
| // must not be altered after this function is called as it will cause a segmentation fault. | ||
| func UnsafeStrToBytes(s string) []byte { | ||
| var buf []byte |
There was a problem hiding this comment.
What do you think about the following to avoid copying the slice internals by directly casting the string:
func unsafeGetBytes(s string) []byte {
return (*[0x7fff0000]byte)(unsafe.Pointer(
(*reflect.StringHeader)(unsafe.Pointer(&s)).Data),
)[:len(s):len(s)]
}
I'm not sure if there are any constraints preventing that but this could be a further optimization
There was a problem hiding this comment.
What is [0x7fff0000]byte? Looks like a big static array. Where did you get that solution from?
There was a problem hiding this comment.
It is the maximum process address space value
I grabbed this suggestion from here:
https://stackoverflow.com/questions/59209493/how-to-use-unsafe-get-a-byte-slice-from-a-string-without-memory-copy
Original source: https://groups.google.com/g/golang-nuts/c/Zsfk-VMd_fU/m/O1ru4fO-BgAJ
|
|
||
| func (c *lruCache) Remove(key []byte) Node { | ||
| if elem, exists := c.dict[string(key)]; exists { | ||
| if elem, exists := c.dict[ibytes.UnsafeBytesToStr(key)]; exists { |
There was a problem hiding this comment.
I'm surprised that this is helpful because, from my understanding, copying during []byte to string conversion when accessing a map by key should be optimized by the Go compiler.
Sources:
There was a problem hiding this comment.
I'm wondering if the benchmark would remain the same as it is right now if the map[string] changes are reverted
There was a problem hiding this comment.
I can check, however for consistency I prefer to keep the casting here.
Co-authored-by: Roman <ackhtariev@gmail.com>
|
After removing the fast convertion, there is a slight performance degradation:
I repeated it few times and the memory allocation results were similar (there was more variation in the ns/op) |
Avoid unnecessary allocation by using fast unsafe bytes -> string conversion
Notes: