From 08be0c9071c0c3cf46e129a5750e3738b2f10d64 Mon Sep 17 00:00:00 2001 From: Dan McGee <87710586+danmcgee-soda@users.noreply.github.com> Date: Fri, 23 Jun 2023 17:30:11 -0500 Subject: [PATCH] Two encoding-related cleanups (#82) * Remove superfluous bitmasking in `encode` We only need to mask with `&0x1F` once per generated character, rather than twice as we did in many cases. As long as the `&0x1F` operation is last, we will always throw away the top three bits as expected. * Remove use of `unsafe` in `String()` method Now that an `Encode()` method was added in #56, it is less necessary to resort to unsafe methods in `String()`. This also appears to have minimal benefit, as seen by these before (using unsafe) and after (without unsafe) benchmarks: Before (using unsafe): % go test -benchmem -bench . goos: darwin goarch: arm64 pkg: github.com/rs/xid BenchmarkNew-8 21845306 52.34 ns/op 0 B/op 0 allocs/op BenchmarkNewString-8 22674129 51.18 ns/op 0 B/op 0 allocs/op BenchmarkFromString-8 286217863 4.233 ns/op 0 B/op 0 allocs/op PASS ok github.com/rs/xid 4.142s After (without unsafe): % go test -benchmem -bench . goos: darwin goarch: arm64 pkg: github.com/rs/xid BenchmarkNew-8 21423278 53.01 ns/op 0 B/op 0 allocs/op BenchmarkNewString-8 21977233 53.67 ns/op 0 B/op 0 allocs/op BenchmarkFromString-8 289641164 4.162 ns/op 0 B/op 0 allocs/op PASS ok github.com/rs/xid 4.181s --- id.go | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/id.go b/id.go index fcd7a04..e88984d 100644 --- a/id.go +++ b/id.go @@ -54,7 +54,6 @@ import ( "sort" "sync/atomic" "time" - "unsafe" ) // Code inspired from mgo/bson ObjectId @@ -172,7 +171,7 @@ func FromString(id string) (ID, error) { func (id ID) String() string { text := make([]byte, encodedLen) encode(text, id[:]) - return *(*string)(unsafe.Pointer(&text)) + return string(text) } // Encode encodes the id using base32 encoding, writing 20 bytes to dst and return it. @@ -206,23 +205,23 @@ func encode(dst, id []byte) { dst[19] = encoding[(id[11]<<4)&0x1F] dst[18] = encoding[(id[11]>>1)&0x1F] - dst[17] = encoding[(id[11]>>6)&0x1F|(id[10]<<2)&0x1F] + dst[17] = encoding[(id[11]>>6)|(id[10]<<2)&0x1F] dst[16] = encoding[id[10]>>3] dst[15] = encoding[id[9]&0x1F] dst[14] = encoding[(id[9]>>5)|(id[8]<<3)&0x1F] dst[13] = encoding[(id[8]>>2)&0x1F] dst[12] = encoding[id[8]>>7|(id[7]<<1)&0x1F] - dst[11] = encoding[(id[7]>>4)&0x1F|(id[6]<<4)&0x1F] + dst[11] = encoding[(id[7]>>4)|(id[6]<<4)&0x1F] dst[10] = encoding[(id[6]>>1)&0x1F] - dst[9] = encoding[(id[6]>>6)&0x1F|(id[5]<<2)&0x1F] + dst[9] = encoding[(id[6]>>6)|(id[5]<<2)&0x1F] dst[8] = encoding[id[5]>>3] dst[7] = encoding[id[4]&0x1F] dst[6] = encoding[id[4]>>5|(id[3]<<3)&0x1F] dst[5] = encoding[(id[3]>>2)&0x1F] dst[4] = encoding[id[3]>>7|(id[2]<<1)&0x1F] - dst[3] = encoding[(id[2]>>4)&0x1F|(id[1]<<4)&0x1F] + dst[3] = encoding[(id[2]>>4)|(id[1]<<4)&0x1F] dst[2] = encoding[(id[1]>>1)&0x1F] - dst[1] = encoding[(id[1]>>6)&0x1F|(id[0]<<2)&0x1F] + dst[1] = encoding[(id[1]>>6)|(id[0]<<2)&0x1F] dst[0] = encoding[id[0]>>3] }