golang []byte和string的高性能转换
golang []byte和string的高性能转换
在fasthttp的最佳实践中有这么一句话:
Avoid conversion between
[]byteandstring, since this may result in memory allocation+copy. Fasthttp API provides functions for both[]byteandstring- use these functions instead of converting manually between[]byteandstring. There are some exceptions - see this wiki page for more details.
大概意思就是说,要尽量避免[]byte和string的转换,因为转换过程会存在内存拷贝,影响性能。此外在fasthttp中还提出了一个解决方案,用于[]byte和string的高性能转换。直接看下源码:
// b2s converts byte slice to a string without memory allocation.
// See https://groups.google.com/forum/#!msg/Golang-Nuts/ENgbUzYvCuU/90yGx7GUAgAJ .
//
// Note it may break if string and/or slice header will change
// in the future go versions.
func b2s(b []byte) string {
/* #nosec G103 */
return *(*string)(unsafe.Pointer(&b))
}
// s2b converts string to a byte slice without memory allocation.
//
// Note it may break if string and/or slice header will change
// in the future go versions.
func s2b(s string) (b []byte) {
/* #nosec G103 */
bh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
/* #nosec G103 */
sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
bh.Data = sh.Data
bh.Cap = sh.Len
bh.Len = sh.Len
return b
}
可以看到上述实现中并没有内存拷贝,使用类似C语言的类型强转实现[]byte和string之间的类型转换。那么他们和一般使用的转换之间的性能差异有多大?看下如下性能测试:
var s = "adsfasdfadsfadsfasdfadfadfasdfasdfadsfasdfasdfasdfsadfas"
func BenchmarkB2sNew(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = s2b(s)
}
}
func BenchmarkB2sNormal(b *testing.B) {
var _ []byte
for i := 0; i < b.N; i++ {
_ = []byte(s)
}
}
var bt = []byte("adsfasdfadsfadsfasdfadfadfasdfasdfadsfasdfasdfasdfsadfas")
func BenchmarkS2BNew(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = b2s(bt)
}
}
func BenchmarkS2BNormal(b *testing.B) {
var _ []byte
for i := 0; i < b.N; i++ {
_ = string(bt)
}
}
测试结果如下:
goos: windows
goarch: amd64
pkg: awesomeProject5/lib
cpu: Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz
BenchmarkB2sNew
BenchmarkB2sNew-8 1000000000 0.2401 ns/op
BenchmarkB2sNormal
BenchmarkB2sNormal-8 40813272 27.49 ns/op
BenchmarkS2BNew
BenchmarkS2BNew-8 1000000000 0.2393 ns/op
BenchmarkS2BNormal
BenchmarkS2BNormal-8 49520067 22.56 ns/op
PASS
可以看到在相同测试条件下,其性能差异竟然达到了100倍!
可见在高频网络访问中,如果直接在[]byte和string之间进行转换将会花费多大的性能!
需要注意的是这种方式也有弊端,在代码注释中可以看到它依赖golang中的string或slice的首部定义。如果后续golang版本对此有修改,则有可能导致代码无法运行。
golang []byte和string的高性能转换的更多相关文章
- 转载 Golang []byte与string转换的一个误区
Golang []byte与string转换的一个误区 https://www.oyohyee.com/post/Note/golang_byte_to_string/ 2019-08-10 23:4 ...
- 如何在Byte[]和String之间进行转换
源自C#与.NET程序员面试宝典. 如何在Byte[]和String之间进行转换? 比特(b):比特只有0 1,1代表有脉冲,0代表无脉冲.它是计算机物理内存保存的最基本单元. 字节(B):8个比特, ...
- golang []byte 和 string相互转换
原文链接:golang []byte和string相互转换 测试例子 package main import ( "fmt" ) func main() { str2 := &qu ...
- go byte 和 string 类型之间转换
string 不能直接和byte数组转换 string可以和byte的切片转换 1,string 转为[]byte var str string = "test" var data ...
- 关于byte[]与string、Image转换
byte[]与string转换 参考网址:https://www.cnblogs.com/xskblog/p/6179689.html 1.使用System.Text.Encoding.Default ...
- golang byte转string 字节数组转字符串的问题
golang语言本身就是c的工具集,开发c的程序用到的大部分结构体,内存管理,携程等,golang基本都有,他只是在这个基础上又加了一些概念这里说一个很小的问题,就是字节数组转string的问题,网上 ...
- golang []byte转string
golang中,字符切片[]byte转换成string最简单的方式是 package main import ( "fmt" _ "unsafe" ) func ...
- java String与Byte[]和String 与InputStream转换时注意编码问题。。。
前一段日子,我在做rsa加密和通过http get方式获取验证码图片通过BitmapFactory创建bitmap 出现了一系列的问题. 通过一系列的调试,发现有些问题原来是在进行String 与By ...
- golang []byte和string相互转换
测试例子 package main import ( "fmt" ) func main() { str2 := "hello" ...
随机推荐
- Spark Ignite踩坑记录
Ignite spark 踩坑记录 简述 ignite访问数据有两种模式: Thin Jdbc模式: Jdbc 模式和Ignite client模式: shell客户端输出问题,不能输出全列: 针对上 ...
- 高德地图——添加标记的两种方法&删除地标记的两种方法
添加标记: 1.marker.setMap(map); 2.marker.add([marker]); 删除标记: 1.marker.setMap(null); 2 map.remove([marke ...
- Linux centos7 -bash: pstree: 未找到命令
2021-08-12 1. 命令简介pstree命令将所有行程以树状图显示,树状图将会以 pid (如果有指定) 或是以 init 这个基本行程为根 (root),如果有指定使用者 id,则树状图会只 ...
- centos7 wget安装Tomcat7
2021-07-15 1.环境介绍 操作系统:centos7 jdk版本:jdk1.8.0.211 tomcat版本:tomcat7.0.109 2. 检查系统中是否已经安装 jdk ,如未安装, 请 ...
- Qt5之反射机制(内省)
Qt的元对象系统除了提供信号/槽机制的特性之外,它还提供了以下特性: QObject::metaObject() 返回关联的元对象 QMetaObject::className() 在运行时状态下返回 ...
- Spring系列之不同数据库异常如何抽象的?
前言 使用Spring-Jdbc的情况下,在有些场景中,我们需要根据数据库报的异常类型的不同,来编写我们的业务代码.比如说,我们有这样一段逻辑,如果我们新插入的记录,存在唯一约束冲突,就会返回给客户端 ...
- Mybatis源码解析4——SqlSession
上一篇文章中,我们介绍了 SqlSessionFactory 的创建过程,忘记了的,可以回顾一下,或者看下下面这张图也行. 接下来,可乐讲给大家介绍 Mybatis 中另一个重量级嘉宾--SqlSes ...
- JDK1.8源码阅读笔记(2) AtomicInteger AtomicLong AtomicBoolean原子类
JDK1.8源码阅读笔记(2) AtomicInteger AtomicLong AtomicBoolean原子类 Unsafe Java中无法直接操作一块内存区域,不能像C++中那样可以自己申请内存 ...
- Intel® QAT 加速卡之IPSec示例
Intel QAT 加速卡之IPSec示例 文章目录 Intel QAT 加速卡之IPSec示例 1. QAT处理IPSec入站报文 2. QAT处理IPSec出站报文 3. 组织架构 4. 示例源码 ...
- Oracle体系结构二