Documentation ¶
Overview ¶
Package exstrings 收集常规的 string 操作,作为 go 标准库 strings 的扩展。 避免重复编写 string 相关操作代码,集中在一起更有利于优化代码,保证代码质量。
这个包会使用一些特殊的操作来减少内存开销,已获得更好的程序性能。
我也会在这个包重写 标准库 strings 里面的一些方法,以适用于不同场景的性能优化。
Index ¶
- Constants
- func BothPad(s, pad string, c int) string
- func Bytes(s string) []byte
- func Copy(src string) string
- func Join(a []string, sep string) string
- func JoinInt16s(v []int16, sep string) string
- func JoinInt32s(v []int32, sep string) string
- func JoinInt64s(v []int64, sep string) string
- func JoinInt8s(v []int8, sep string) string
- func JoinInts(v []int, sep string) string
- func JoinToBytes(a []string, sep string) []byte
- func JoinUint16s(v []uint16, sep string) string
- func JoinUint32s(v []uint32, sep string) string
- func JoinUint64s(v []uint64, sep string) string
- func JoinUint8s(v []uint8, sep string) string
- func JoinUints(v []uint, sep string) string
- func LeftPad(s, pad string, c int) string
- func Pad(s, pad string, c, falg int) string
- func Repeat(s string, count int) string
- func RepeatToBytes(s string, count int) []byte
- func Replace(s, old, new string, n int) string
- func ReplaceToBytes(s, old, new string, n int) []byte
- func Reverse(s string) string
- func ReverseASCII(s string) string
- func RightPad(s, pad string, c int) string
- func SubString(s string, start, length int) string
- func UnsafeBothPad(s, pad string, c int) string
- func UnsafeJoin(a []string, sep string) stringdeprecated
- func UnsafeLeftPad(s, pad string, c int) string
- func UnsafePad(s, pad string, c, falg int) stringdeprecated
- func UnsafeRepeat(s string, count int) stringdeprecated
- func UnsafeReplace(s, old, new string, n int) stringdeprecated
- func UnsafeReplaceToBytes(s, old, new string, n int) []byte
- func UnsafeReverseASCII(s string) string
- func UnsafeRightPad(s, pad string, c int) string
- func UnsafeToBytes(s string) []byte
Constants ¶
const ( // PadLeft 在左侧填充字符串为指定长度。 PadLeft = iota // PadBoth 在两边填充字符串为指定长度,如果补充长度是奇数,右边的字符会更多一些。 PadBoth // PadRight 在右侧填充字符串为指定长度。 PadRight )
Variables ¶
This section is empty.
Functions ¶
func Bytes ¶ added in v1.1.0
Bytes 把字符串转换成 []byte 类型,和 []byte(s) 操作结果一致,但是效率更高。
我进行了性能测试,它相比 []byte(s) 性能提升大约 14%,这仅仅是个实验的函数,它可能随着编译器优化而失去性能优势。 极端性能情况下依然可以使用它,它永远和 []byte(s) 的结果一致。
BenchmarkStandardLibraryStringToBytes-8 18584335 58.4 ns/op 192 B/op 1 allocs/op BenchmarkExstringsStringToBytes-8 23752122 50.1 ns/op 192 B/op 1 allocs/op
func Copy ¶ added in v1.1.0
Copy 拷贝一个字符串,在截取字符串之后,我们得到一个大字符串的引用,这会导致内存泄漏。 如果我们引用一个较大字符串的子串,建议进行 copy 以便 GC 可以快速回收大字符串。 例如: exstrings.Copy(s[10:50]) 这会得到一个子串的拷贝,原字符串不使用可以被 GC 回收。
func JoinInt16s ¶
JoinInt16s 使用 sep 连接 []int16 并返回连接的字符串
func JoinInt32s ¶
JoinInt32s 使用 sep 连接 []int32 并返回连接的字符串
func JoinInt64s ¶
JoinInt64s 使用 sep 连接 []int64 并返回连接的字符串
func JoinToBytes ¶
JoinToBytes 使用 sep 连接 a 的字符串并返回 []byte 该方法是对标准库 strings.Join 修改,配合 unsafe 包能有效减少内存分配。
func JoinUint16s ¶
JoinUint16s 使用 sep 连接 []uint16 并返回连接的字符串
func JoinUint32s ¶
JoinUint32s 使用 sep 连接 []uint32 并返回连接的字符串
func JoinUint64s ¶
JoinUint64s 使用 sep 连接 []uint64 并返回连接的字符串
func JoinUint8s ¶
JoinUint8s 使用 sep 连接 []uint8 并返回连接的字符串
func Pad ¶
Pad 使用另一个字符串填充字符串为指定长度。
该函数返回 s 被从左端、右端或者同时两端被填充到制定长度后的结果。 填充方向由 falg 控制,可选值:PadLeft、PadBoth、PadRight。
在两边填充字符串为指定长度,如果补充长度是奇数,右边的字符会更多一些。
func Repeat ¶
Repeat 返回由字符串s的计数副本组成的新字符串。 该方法是对标准库 strings.Repeat 修改,对于创建大字符串能有效减少内存分配。
如果计数为负或 len(s) * count 溢出将触发panic。
func RepeatToBytes ¶
RepeatToBytes 返回由字符串s的计数副本组成的 []byte。 该方法是对标准库 strings.Repeat 修改,对于创建大字符串能有效减少内存分配。
如果计数为负或 len(s) * count 溢出将触发panic。
func ReplaceToBytes ¶
ReplaceToBytes 替换字符串,并返回 []byte,减少类型转换 如果在字符串串中找不到子串,会发生内存拷贝 这个方法返回的 []byte 是安全,可以进行修改
func Reverse ¶
Reverse 反转字符串,通过 https://golang.org/doc/code.html#Library 收集 使用 utf8.DecodeRuneInString 改进性能,请见:https://github.com/thinkeridea/go-extend/issues/5
func ReverseASCII ¶ added in v1.0.1
ReverseASCII 反转字符串, 只支持单字节编码,可以提供更快的反转
func SubString ¶ added in v1.1.0
SubString 是 exutf8.RuneSubString 的别名,提供字符数量截取字符串的方法,针对多字节字符安全高效的截取 如果 start 是非负数,返回的字符串将从 string 的 start 位置开始,从 0 开始计算。例如,在字符串 “abcdef” 中,在位置 0 的字符是 “a”,位置 2 的字符串是 “c” 等等。 如果 start 是负数,返回的字符串将从 string 结尾处向前数第 start 个字符开始。 如果 string 的长度小于 start,将返回空字符串。
如果提供了正数的 length,返回的字符串将从 start 处开始最多包括 length 个字符(取决于 string 的长度)。 如果提供了负数的 length,那么 string 末尾处的 length 个字符将会被省略(若 start 是负数则从字符串尾部算起)。如果 start 不在这段文本中,那么将返回空字符串。 如果提供了值为 0 的 length,返回的子字符串将从 start 位置开始直到字符串结尾。
func UnsafeBothPad ¶
UnsafeBothPad 使用另一个字符串从两端填充字符串为指定长度, 如果补充长度是奇数,右边的字符会更多一些。
该函数使用 unsafe 包转换数据类型,降低内存分配。 Deprecated: 不在使用 Unsafe 前缀
func UnsafeJoin
deprecated
func UnsafeLeftPad ¶
UnsafeLeftPad 使用另一个字符串从左端填充字符串为指定长度。
该函数使用 unsafe 包转换数据类型,降低内存分配。 Deprecated: 不在使用 Unsafe 前缀
func UnsafeRepeat
deprecated
UnsafeRepeat 返回由字符串s的计数副本组成的新字符串。 该方法是对标准库 strings.Repeat 修改,对于创建大字符串能有效减少内存分配。
如果计数为负或 len(s) * count 溢出将触发panic。
与标准库的性能差异(接近标准库性能的两倍):
BenchmarkUnsafeRepeat-8 50000 28003 ns/op 303104 B/op 1 allocs/op BenchmarkStandardLibraryRepeat-8 30000 50619 ns/op 606208 B/op 2 allocs/op
Deprecated: 不在使用 Unsafe 前缀,保持与标准库相同的命名
func UnsafeReplace
deprecated
func UnsafeReplaceToBytes ¶
UnsafeReplaceToBytes 替换字符串,并返回 []byte,减少类型转换 如果输入是字面量字符串,返回结果不可以修改
func UnsafeReverseASCII ¶ added in v1.0.1
UnsafeReverseASCII 反转字符串, 只支持单字节编码,不支持字面量字符串, 原地反转字符串,可以提供更快的性能,但需要注意安全。
func UnsafeRightPad ¶
UnsafeRightPad 使用另一个字符串从右端填充字符串为指定长度。
该函数使用 unsafe 包转换数据类型,降低内存分配。 Deprecated: 不在使用 Unsafe 前缀
func UnsafeToBytes ¶
UnsafeToBytes 把 string 转换为 []byte 没有多余的内存开销。
这个函数可以提升 string 转 []byte 的性能,并极大的降低内存开销,但是却相当的危险,对于不明确这个函数的人来说不建议使用该函数。
这个函数是 exbytes.ToString 反向操作版,但是不像 exbytes.ToString 那么的稳定安全,该函数使用不当会导致程序直接崩溃,且无法恢复。
s := `{"k":"v"}` b := exstrings.UnsafeToBytes(s) // b[3] = 'k' // unexpected fault address 0x1118180 data := map[string]string{} err := json.Unmarshal(b, &data) fmt.Println(data, err)
这是一个使用的例子,如果我们需要转换一个字符串很方便,且开销非常的低。 但是一定要注意,b[3] = 'k' 如果尝试修改获得的 []byte 将直接导致程序崩溃,并且不可能通过 recover() 恢复。
实际上我们可以突破这个限制,这就要了解字符串的一些规则,下面的例子可以完美运行,并修改字符串:
s := strings.Repeat("A", 3) b := exstrings.UnsafeToBytes(s) b[1] = 'B' b[2] = 'C' fmt.Println(s, string(b))
非常完美,s和b变量的值都是 ABC, 为什么会这样呢?
这个就是 string 的内存分配方法, 字面量使用这种方式是没有办法修改的,因为这是在编译时就决定的,编译时会设定字符串的内存数据是只读数据。 如果程序运行时生成的数据,这种数据是可以安全使用该函数的,但是要当心你的字符串可能会被修改, 比如我们调用 json.Unmarshal(exstrings.UnsafeToBytes(s), &data), 如果 json 包里面出现修改输入参数,那么原来的字符串就可能不是你想想的那样。
使用该函数要明确两个事情:
- 确定字符串是否是字面量,或者内存被分配在只读空间上。
- 确保访问该函数结果的函数是否会按照你的意愿访问或修改数据。
我公开该函数经过很多思考,虽然它很危险,但是有时间却很有用,如果我们需要大批量转换字符串的大小写,而且不再需要原字符串,我们可以原地安全的修改字符串。 当然还有更多的使用方法,可以极大的提升我们程序的性能。
Types ¶
This section is empty.