Golang性能优化技巧(一)

概述

本文介绍string和[]byte的转换,在某些场景下合理的转换方式可以提升服务的整体性能。

背景介绍

string和[]byte的底层数据结构不一致

Type string
Struct string {
    Uint8* str;
    Int.   len
}


Type []byte
Struct []uint8 {
    Uint8* array;
    Int len;
    Int cap;
}

使用通常的类型转换方式,会复制整个字符串。如不修改数据,仅转换类型,可避开复制,提升性能。

方式

string 可看做 [2]uintptr,而 [ ]byte 则是 [3]uintptr。如此,str2bytes 只需构建 [3]uintptr{ptr, len, len},而 bytes2str 更简单,直接转换指针类型,忽略掉 cap 即可。

func str2bytes(s string) []byte {
    x := (*[2]uintptr)(unsafe.Pointer(&s))
    h := [3]uintptr{x[0], x[1], x[1]}
    return *(*[]byte)(unsafe.Pointer(&h))
}
 
func bytes2str(b []byte) string {
    return *(*string)(unsafe.Pointer(&b))
}

解释

  1. 只是进行了(地址)值拷贝,并没有对*uint指针指向的所有字符挨个拷贝;
  2. 只能对不改变变量值的场景下使用,一旦改变其中一个值,会对另一个值造成影响,虽然代码上看不出任何的痕迹;
  3. 使用上述方式,仅仅对于(地址)值进行了拷贝,但它仍然是有代价的。也就是只有字符串的长度越长时,节省的拷贝工作越多,反之则不那么明显;
  4. 除了避免字符串的拷贝以外,使用上述函数的另一个好处是减轻了gc的压力,因而整体性能也会更好。

参考文献

https://segmentfault.com/a/1190000005006351

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值