当我们使用GO进行数据序列化或后序操作时,我们通常可能涉及字符串和字节数组的转换。例如:
JSON序列化是[]字节类型,需要将其转换为字符串类型。当数据量为小时时,可以忽略类型转换的开销,但是当数据增加的量增加时,它可能会成为性能瓶颈。使用有效的转换方法可以减少该领域的费用
在了解其翻译方式之前,您需要了解基础数据结构
本文基于GO 1.13.12
细绳:
片:
与切片的结构相比,字符串缺少指示容量的帽字段,因此不能用于使用构建的-in Cap()函数traverse String
那么,为什么字符串不需要帽字段?
因为它不应添加诸如slice之类的元素,所以不必确定盖帽字段是否可以确定它是否超过了基础数组的能力来决定是否扩展
只有LEN属性不会影响范围的读取操作,因为范围操作仅决定是否根据Len跳出循环
那么为什么字符串将其设置为非变换?因为这可以确保字符串的底层不更改
例如,地图基于字符串。如果基础字符数组变化,则计算出的哈希值也将变化,因此从地图定位时找不到上一个值,因此其非变化的特殊性能将使这种情况变得更加明智,字符串也适合作为地图密钥此外,无法变量功能还可以确保数据的线程安全性
非变量字符串有很多好处。为了维护其无法可变特性,字符串和字节数组切换通常通过数据复制来实现:
此方法很简单,但是如果复制了基础数据,则将两对和谐的功能调用转换为一对和谐,在编译期间
字符串到[]字节
根据退货值是否逃到堆以及BUF的长度是否足够,确定使用BUF或致电申请Slice的选择。但是无论哪种方式,您都将执行该副本基础数据
[]字节到字符串
首先,处理长度为0或1,然后判断BUF的使用或通过新应用程序应用新应用程序,但是无论哪种方式,必须在最后复制数据
这是转换字符串之后字符串的LEN属性
如果程序保证了基础数据未经修改,只能更改类型而不复制数据,它可以提高性能吗?
unsafe.pointer,int,uintpt,相同的内存大小
因此,从基础结构的角度来看,字符串可以看到[2] uintptr,[]]字节切片类型被视为[3] uintptr
然后只需要构建[3] uintptr {ptr,len,len}从字符串到[]字节
在这里,我们为切片结构生成了盖字段。实际上,CAP字段对读取操作没有影响,但是如果要转换开关片的附加元素,可能会有问题。它可能大于LEN,因此,当Apend不会打开新的内存存储时元素,但将其添加在原始数组后面。
[]字节到字符串更简单,您可以直接转换指针的类型,忽略CAP字段
实施如下:
Unsafe.pointer这里用于转换不同类型的指针,而无需复制基础数据
接下来,执行性能测试有效实现。这里
测试以下4种方法:
测试结果如下:
可以看出,性能差距相对较大。
本文介绍了字符串和数组的基础数据结构以及有效的传输方法。应当指出,它适用于可以确保不修改基础数据的程序。如果不能保证并且可以修改基础数据,则可能会导致异常,并且仍然使用复制方法。
