tinylib / msgp

A Go code generator for MessagePack / msgpack.org[Go]
MIT License
1.81k stars 192 forks source link

use unsafe.String #371

Closed karelbilek closed 1 month ago

karelbilek commented 1 month ago

since go1.20, there is unsafe.String/unsafe.StringData

Looks like this

// to convert string to byte slice
unsafe.Slice(unsafe.StringData(s), len(s))

// to convert byte slice to string
return unsafe.String(&b[0], len(b))

I have found these functions really fast. (and it's also much faster to directly inline their usage rather than put them in a wrapper function, btw.)

I think those might be useful here. I will try to have a look where would I add them :D

karelbilek commented 1 month ago

See

https://github.com/golang/go/issues/53003

karelbilek commented 1 month ago

I see that you actually use

func UnsafeString(b []byte) string {
    return *(*string)(unsafe.Pointer(&b))
}

which should be roughly the same. So.... I guess it's the same

klauspost commented 1 month ago

You are welcome to send a PR as a cosmetic fix. We are at minimum Go 1.20, so it should be fine.

karelbilek commented 1 month ago

I will first try to bench first if it makes anything faster.

klauspost commented 1 month ago

99% sure it will be the same. I am willing to be surprised, though :)

karelbilek commented 1 month ago

yeah it seems exactly the same with regards to speed, even when I inline; not sure why my earlier experiments were so different, probably noise. OK I will make a PR but it will be really just a cosmetic change

philhofer commented 1 month ago

FWIW the UnsafeString function was used by the code generator to turn slices into strings temporarily so that we could switch on them when decoding structs. This was back before the compiler understood that it could avoid any allocations when you wrote switch string(buf) { case "xyz": ... }. Nowadays it's no longer necessary.