go.sdls.io/sin@v0.0.9/internal/bytesconv/bytesconv_test.go (about) 1 // Copyright 2020 Gin Core Team. All rights reserved. 2 // Use of this source code is governed by a MIT style 3 // license that can be found in the LICENSE file. 4 5 package bytesconv 6 7 import ( 8 "bytes" 9 "math/rand" 10 "strings" 11 "testing" 12 "time" 13 ) 14 15 var ( 16 testString = "Albert Einstein: Logic will get you from A to B. Imagination will take you everywhere." 17 testBytes = []byte(testString) 18 ) 19 20 func rawBytesToStr(b []byte) string { 21 return string(b) 22 } 23 24 func rawStrToBytes(s string) []byte { 25 return []byte(s) 26 } 27 28 // go test -v 29 30 func TestBytesToString(t *testing.T) { 31 data := make([]byte, 1024) 32 for i := 0; i < 100; i++ { 33 // #nosec G404 34 _, _ = rand.Read(data) 35 if rawBytesToStr(data) != BytesToString(data) { 36 t.Fatal("don't match") 37 } 38 } 39 } 40 41 const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 42 const ( 43 letterIdxBits = 6 // 6 bits to represent a letter index 44 letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits 45 letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits 46 ) 47 48 var src = rand.NewSource(time.Now().UnixNano()) 49 50 func RandStringBytesMaskImprSrcSB(n int) string { 51 sb := strings.Builder{} 52 sb.Grow(n) 53 // A src.Int63() generates 63 random bits, enough for letterIdxMax characters! 54 for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; { 55 if remain == 0 { 56 cache, remain = src.Int63(), letterIdxMax 57 } 58 if idx := int(cache & letterIdxMask); idx < len(letterBytes) { 59 sb.WriteByte(letterBytes[idx]) 60 i-- 61 } 62 cache >>= letterIdxBits 63 remain-- 64 } 65 66 return sb.String() 67 } 68 69 func TestStringToBytes(t *testing.T) { 70 for i := 0; i < 100; i++ { 71 s := RandStringBytesMaskImprSrcSB(64) 72 if !bytes.Equal(rawStrToBytes(s), StringToBytes(s)) { 73 t.Fatal("don't match") 74 } 75 } 76 } 77 78 // go test -v -run=none -bench=^BenchmarkBytesConv -benchmem=true 79 80 func BenchmarkBytesConvBytesToStrRaw(b *testing.B) { 81 for i := 0; i < b.N; i++ { 82 rawBytesToStr(testBytes) 83 } 84 } 85 86 func BenchmarkBytesConvBytesToStr(b *testing.B) { 87 for i := 0; i < b.N; i++ { 88 BytesToString(testBytes) 89 } 90 } 91 92 func BenchmarkBytesConvStrToBytesRaw(b *testing.B) { 93 for i := 0; i < b.N; i++ { 94 rawStrToBytes(testString) 95 } 96 } 97 98 func BenchmarkBytesConvStrToBytes(b *testing.B) { 99 for i := 0; i < b.N; i++ { 100 StringToBytes(testString) 101 } 102 }