golang []byte和string的高性能转换

fasthttp的最佳实践中有这么一句话:

Avoid conversion between []byte and string, since this may result in memory allocation+copy. Fasthttp API provides functions for both []byte and string - use these functions instead of converting manually between []byte and string. There are some exceptions - see this wiki page for more details.

大概意思就是说,要尽量避免[]bytestring的转换,因为转换过程会存在内存拷贝,影响性能。此外在fasthttp中还提出了一个解决方案,用于[]bytestring的高性能转换。直接看下源码:

// 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语言的类型强转实现[]bytestring之间的类型转换。那么他们和一般使用的转换之间的性能差异有多大?看下如下性能测试:

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倍!

可见在高频网络访问中,如果直接在[]bytestring之间进行转换将会花费多大的性能!

需要注意的是这种方式也有弊端,在代码注释中可以看到它依赖golang中的string或slice的首部定义。如果后续golang版本对此有修改,则有可能导致代码无法运行。

golang []byte和string的高性能转换的更多相关文章

  1. 转载 Golang []byte与string转换的一个误区

    Golang []byte与string转换的一个误区 https://www.oyohyee.com/post/Note/golang_byte_to_string/ 2019-08-10 23:4 ...

  2. 如何在Byte[]和String之间进行转换

    源自C#与.NET程序员面试宝典. 如何在Byte[]和String之间进行转换? 比特(b):比特只有0 1,1代表有脉冲,0代表无脉冲.它是计算机物理内存保存的最基本单元. 字节(B):8个比特, ...

  3. golang []byte 和 string相互转换

    原文链接:golang []byte和string相互转换 测试例子 package main import ( "fmt" ) func main() { str2 := &qu ...

  4. go byte 和 string 类型之间转换

    string 不能直接和byte数组转换 string可以和byte的切片转换 1,string 转为[]byte var str string = "test" var data ...

  5. 关于byte[]与string、Image转换

    byte[]与string转换 参考网址:https://www.cnblogs.com/xskblog/p/6179689.html 1.使用System.Text.Encoding.Default ...

  6. golang byte转string 字节数组转字符串的问题

    golang语言本身就是c的工具集,开发c的程序用到的大部分结构体,内存管理,携程等,golang基本都有,他只是在这个基础上又加了一些概念这里说一个很小的问题,就是字节数组转string的问题,网上 ...

  7. golang []byte转string

    golang中,字符切片[]byte转换成string最简单的方式是 package main import ( "fmt" _ "unsafe" ) func ...

  8. java String与Byte[]和String 与InputStream转换时注意编码问题。。。

    前一段日子,我在做rsa加密和通过http get方式获取验证码图片通过BitmapFactory创建bitmap 出现了一系列的问题. 通过一系列的调试,发现有些问题原来是在进行String 与By ...

  9. golang []byte和string相互转换

    测试例子 package main   import (     "fmt" )   func main() {     str2 := "hello"     ...

随机推荐

  1. BUUCTF-[CISCN2019 总决赛 Day2 Web1]Easyweb

    BUUCTF-[CISCN2019 总决赛 Day2 Web1]Easyweb 就给了一个这个... 先打上robots.txt看看 发现有源码备份,但不是index.php.bak... 看源码发现 ...

  2. 使用selenium模拟登录12306网站

    1 import yh 2 from selenium import webdriver 3 from PIL import Image 4 # from selenium.webdriver imp ...

  3. JVM双亲委派模型及其优点

    JVM双亲委派模型及其优点 什么是双亲委派模型? 双亲委派模型: ​ 如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行,如果父类加载器还存在其父类加载器, ...

  4. 2021秋 noip 模拟赛

    9.9 T3 第负二题 \(f_i\) 的数学意义:中心在第 \(i\) 行的全 \(1\) 组成的最大正方形(对角线水平/竖直),对角线长 \(2f_i-1\). 显然 \(f_i\) 具有单调性( ...

  5. dubbo 2.7应用级服务发现踩坑小记

    本文已收录 https://github.com/lkxiaolou/lkxiaolou 欢迎star. 背景 本文记录最近一位读者反馈的dubbo 2.7.x中应用级服务发现的问题,关于dubbo应 ...

  6. 找不到方法:“Void System.Data.Objects.ObjectContextOptions.set_UseConsistentNullReferenceBehavior(Boolean)

    找不到方法:"Void System.Data.Objects.ObjectContextOptions.set_UseConsistentNullReferenceBehavior(Boo ...

  7. GMAP.NET系列学习文档

    http://www.cnblogs.com/enjoyeclipse/archive/2013/01/13/2858392.html http://www.cnblogs.com/luxiaoxun ...

  8. 论文解读《Momentum Contrast for Unsupervised Visual Representation Learning》俗称 MoCo

    论文题目:<Momentum Contrast for Unsupervised Visual Representation Learning> 论文作者: Kaiming He.Haoq ...

  9. android开发使用jxl创建Excel

    这周水了几天,今天把博客赶上,找找状态. 周五的时候终于完成了课堂测试第二阶段,主要的难点就是生成Excel表并将填写的数据插入到Excel表中. 一.jxl使用 1.创建或读取一个工作薄 Workb ...

  10. 30天自制操作系统(二)汇编语言学习和Makefile入门

    我们继续学习操作系统的相关内容. ; hello-os ; TAB=4 ORG 0x7c00 ; このプログラムがどこに読み込まれるのか ; 以下は標準的なFAT12フォーマットフロッピーディスクのた ...