golang string转换为[]byte
golang中将string转换为byte切片,可以使用标准转换方法,也可以通过强转方式。两种方式的结果一样,但是执行效率差别很大。如下是我的两种转化方式,效率比标准的转换高很多。
在贴代码前,先了解一下string和slice的Header定义
StringHeader如下,他是string的底层实现
type StringHeader struct {
Data uintptr
Lenint
}
SliceHeader如下
type SliceHeader struct {
Data uintptr
Lenint
Capint
}
可以发现这两个非常相似
其实就非常好理解了
Data指向实际内容的数组
Len长度
那么我们就可以开始如下两种操作
- 将StringHeader中的Data赋值给SliceHeader的Data
将StringHeader中的Len赋值给SliceHeader的Len - 也可以直接将StringHeader强转成SliceHeader(因为各个fields的长度和顺序都是一样的)
func string2BytesSlicePlus(str string) []byte {
bytesSlice := []byte{} //此处定义了一个空切片
stringData := &(*(*reflect.StringHeader)(unsafe.Pointer(&str))).Data//取得StringHeader的Data地址
byteSliceData := &(*(*reflect.SliceHeader)(unsafe.Pointer(&bytesSlice))).Data //取得SliceHeader的Data地址
*byteSliceData = https://www.it610.com/article/*stringData //将StringHeader.Data的值赋给SliceHeader.Data
(*(*reflect.SliceHeader)(unsafe.Pointer(&bytesSlice))).Len = (*(*reflect.StringHeader)(unsafe.Pointer(&str))).Len //设置长度return bytesSlice
}
【golang string转换为[]byte】直接强转
func string2BytesSlicePlus2(str string) []byte {
strSliceHeader := *(*reflect.StringHeader)(unsafe.Pointer(&str))
byteSlice := *(*[]byte)(unsafe.Pointer(&strSliceHeader))return byteSlice
}
const (
TOTALCNT = 1000000
)func string2BytesSlicePlus(str string) []byte {
bytesSlice := []byte{}
stringData := &(*(*reflect.StringHeader)(unsafe.Pointer(&str))).Data
byteSliceData := &(*(*reflect.SliceHeader)(unsafe.Pointer(&bytesSlice))).Data
*byteSliceData = https://www.it610.com/article/*stringData
(*(*reflect.SliceHeader)(unsafe.Pointer(&bytesSlice))).Len = (*(*reflect.StringHeader)(unsafe.Pointer(&str))).Lenreturn bytesSlice
}func string2BytesSlicePlus2(str string) []byte {
strSliceHeader := *(*reflect.StringHeader)(unsafe.Pointer(&str))
byteSlice := *(*[]byte)(unsafe.Pointer(&strSliceHeader))return byteSlice
}func normalString2BytesSlice(str string) []byte {
return []byte(str)
}func TestStringConvert(t *testing.T) {
origStr :="String convert test"convSlice := string2BytesSlicePlus(origStr)byteSlice := []byte(origStr)if !bytes.Equal(convSlice, byteSlice) {
t.Fail()
}convSlice = string2BytesSlicePlus2(origStr)
if !bytes.Equal(convSlice, byteSlice) {
t.Fail()
}
}//Run go test -bench="." -benchmem to verify efficiency
func Benchmark_NormalConvert(t *testing.B) {
for count := 0;
count < TOTALCNT;
count++ {
str := "This is string to byte slice convert test!!!"
_ = normalString2BytesSlice(str)
}
}func Benchmark_PlusConvert(t *testing.B) {
for count := 0;
count < TOTALCNT;
count++ {
str := "This is string to byte slice convert test!!!"
_ = string2BytesSlicePlus(str)
}
}func Benchmark_PlusConvert2(t *testing.B) {
for count := 0;
count < TOTALCNT;
count++ {
str := "This is string to byte slice convert test!!!"
_ = string2BytesSlicePlus2(str)
}
}
执行测试
go test -bench="." -benchmem
测试结果
cpu: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
Benchmark_NormalConvert-1210000000000.03040 ns/op0 B/op0 allocs/op
Benchmark_PlusConvert-1210000000000.0002572 ns/op0 B/op0 allocs/op
Benchmark_PlusConvert2-1210000000000.0002586 ns/op0 B/op0 allocs/op
PASS
okjianghu.com/godemo/000Tips/T0018/test0.315s
根据结果可以看出
使用标准方法[]byte(str)转换的效率最低
使用自定义的两种方法几乎无差别,效率要高很多百倍的效率差别
推荐阅读
- 一起来学习C语言的字符串转换函数
- 视频转换器哪种好用()
- 以太坊中的计量单位及相互转换
- jvm关于String
- LeetCode(03)Longest|LeetCode(03)Longest Substring Without Repeating Characters
- 怎么将桌面上的CAD图纸添加到软件中进行BMP格式转换()
- 三门问题(蒙提霍尔悖论)分析与Golang模拟
- NAT(网络地址转换技术)
- golang锁竞争性能
- js类型转换和内存