go语言扩展包,收集一些常用的操作函数,辅助更快的完成开发工作,并减少重复代码

Overview

go-extend

GoDoc Actions Status codecov Go Report Card GitHub release

go-extend 收集一些常用的操作函数,辅助更快的完成开发工作,并减少重复代码。

它收集各种杂项函数,并进行归类,方便使用者查找,它可以大幅度提升开发效率和程序运行性能。它以保证性能为最大前提,提供有效的方法。 针对一些标准库中的函数或者库进行一些修改,使其性能大幅度提升,但它并不用来替换标准库函数,这些函数往往会在一些场景下有效,但有些函数可以用来替换标准库函数,它们保持一致的功能,且相当安全。

一些包或者函数使用示例及分析可以在我的 博客(https://blog.thinkeridea.com) 中找到。

安装

$ go get  github.com/thinkeridea/go-extend/...

规范:

  • 与标准库包名一致的使用 ex 前缀, 避免与标准库包冲突
  • 包目录下 doc.go 作为包说明文档

性能测试

包中一些函数会进行性能测试,包括每次修订的性能对比,它们一般位于各自包下面的 benchmark 目录下,性能测试结果可以在 benchmark.md 快速浏览。

标准库函数改进列表

用来替换标准库的函数,它们和标准库函数功能保持一致,并拥有更好的性能:

  • exstrings.Join 该方法是对标准库 strings.Join 修改,配合 unsafe 包能有效减少内存分配
  • exstrings.Repeat 该方法是对标准库 strings.Repeat 修改,对于创建大字符串能有效减少内存分配
  • exstrings.Replace 替换字符串 该方法是对标准库 strings.Replace 修改,配合 unsafe 包能有效减少内存分配

用该改善标准库的函数,它们基本和标准库功能一致,但是它们都拥有更好的性能:

许可

go-extend 根据 MIT License 许可证授权,有关完整许可证文本,请参阅 LICENSE

Issues
  • exstrings.Reverse 性能改进

    exstrings.Reverse 性能改进

    该方法收集于官网 How to write Go code 中的一个代码片段,因曾经面试遇到这个面试题而留心。

    近期回答 Go Forum 中关于 [SOLVED] String size of 20 character 中字符串长度截取使用 []rune 类型与字符串类型转换,期望处理安全的 unicode 字符。

    我对此方法提出了性能质疑,编写了基于 utf8.DecodeRuneInString 的计算版本,并做了性能测试 相关回复在这里 发现两个种方法性能差距惊人。

    我想到了 go-extend 中的 exstrings.Reverse 方法也是用了类似的类型转换,所以我做了一个小的实验来测试不同实现的性能。

    optimize 
    opened by thinkeridea 5
  • Update: UnsafeToBytes

    Update: UnsafeToBytes

    More faster

    $ go test -count=50 -bench=BenchmarkUnsafeToBytes > old.txt
    $ go test -count=50 -bench=BenchmarkUnsafeToBytes > new.txt
    
    $ benchcmp old.txt new.txt           
    benchmark                    old ns/op     new ns/op     delta
    BenchmarkUnsafeToBytes-4     0.50          0.38          -22.78%
    BenchmarkUnsafeToBytes-4     0.36          0.35          -2.77%
    BenchmarkUnsafeToBytes-4     0.55          0.35          -35.75%
    BenchmarkUnsafeToBytes-4     0.37          0.36          -4.03%
    BenchmarkUnsafeToBytes-4     0.33          0.35          +4.50%
    BenchmarkUnsafeToBytes-4     0.36          0.35          -2.79%
    BenchmarkUnsafeToBytes-4     0.33          0.33          +0.60%
    BenchmarkUnsafeToBytes-4     0.35          0.33          -5.17%
    BenchmarkUnsafeToBytes-4     0.35          0.34          -4.51%
    BenchmarkUnsafeToBytes-4     0.36          0.33          -8.94%
    BenchmarkUnsafeToBytes-4     0.38          0.33          -13.09%
    BenchmarkUnsafeToBytes-4     0.36          0.34          -5.28%
    BenchmarkUnsafeToBytes-4     0.37          0.35          -5.08%
    BenchmarkUnsafeToBytes-4     0.37          0.43          +14.75%
    BenchmarkUnsafeToBytes-4     0.35          0.35          +0.29%
    BenchmarkUnsafeToBytes-4     0.35          0.37          +7.23%
    BenchmarkUnsafeToBytes-4     0.39          0.36          -7.24%
    BenchmarkUnsafeToBytes-4     0.36          0.36          -0.28%
    BenchmarkUnsafeToBytes-4     0.35          0.35          +0.57%
    BenchmarkUnsafeToBytes-4     0.35          0.34          -3.97%
    BenchmarkUnsafeToBytes-4     0.34          0.34          -0.29%
    BenchmarkUnsafeToBytes-4     0.33          0.35          +6.01%
    BenchmarkUnsafeToBytes-4     0.39          0.34          -14.10%
    BenchmarkUnsafeToBytes-4     0.55          0.34          -38.84%
    BenchmarkUnsafeToBytes-4     0.41          0.34          -17.23%
    BenchmarkUnsafeToBytes-4     0.38          0.36          -2.67%
    BenchmarkUnsafeToBytes-4     0.37          0.38          +2.71%
    BenchmarkUnsafeToBytes-4     0.37          0.34          -7.65%
    BenchmarkUnsafeToBytes-4     0.42          0.34          -18.25%
    BenchmarkUnsafeToBytes-4     0.37          0.37          -1.88%
    BenchmarkUnsafeToBytes-4     0.37          0.36          -2.73%
    BenchmarkUnsafeToBytes-4     0.41          0.35          -14.56%
    BenchmarkUnsafeToBytes-4     0.35          0.35          +2.31%
    BenchmarkUnsafeToBytes-4     0.35          0.36          +1.98%
    BenchmarkUnsafeToBytes-4     0.37          0.36          -2.72%
    BenchmarkUnsafeToBytes-4     0.39          0.34          -11.11%
    BenchmarkUnsafeToBytes-4     0.47          0.35          -26.27%
    BenchmarkUnsafeToBytes-4     0.39          0.34          -11.40%
    BenchmarkUnsafeToBytes-4     0.43          0.36          -16.47%
    BenchmarkUnsafeToBytes-4     0.36          0.34          -5.22%
    BenchmarkUnsafeToBytes-4     0.36          0.37          +0.82%
    BenchmarkUnsafeToBytes-4     0.39          0.34          -12.73%
    BenchmarkUnsafeToBytes-4     0.40          0.36          -9.00%
    BenchmarkUnsafeToBytes-4     0.39          0.34          -13.55%
    BenchmarkUnsafeToBytes-4     0.36          0.40          +11.36%
    BenchmarkUnsafeToBytes-4     0.60          0.36          -40.73%
    BenchmarkUnsafeToBytes-4     0.36          0.34          -6.58%
    BenchmarkUnsafeToBytes-4     0.38          0.33          -12.37%
    BenchmarkUnsafeToBytes-4     0.39          0.33          -13.47%
    BenchmarkUnsafeToBytes-4     0.39          0.34          -13.40%
    
    opened by awesee 2
  • 动态评估bytes.Buffer的需求的容量,全局共享bytes.Buffer池

    动态评估bytes.Buffer的需求的容量,全局共享bytes.Buffer池

    采用全局共享不同容量区间(采用2的幂次方来划分),一共 22 个区间,最小64 byte, 最大 256 MB, 根据动态计算,在获取 bytes.Buffer 时从相应桶的 sync.Pool 来获取,以减少多余的内存浪费及bytes.Buffer 扩容次数。

    相较于使用固定容量的 sync.Pool 在需求容量动态波动时可以获取30~40倍的性能提升(这并不包含GC带来的性能提升,那将是更令人兴奋的),在内存分配上可以减少近300倍。

    即使在每次都获取固定容量,且不发生扩容的情况(这会导致动态池只是用单个桶), sync.Pool并没有带来很大的惊喜,动态池相较于 sync.Pool 性能略下降 28%, 单次约 17ns, 即使这样这依然让人振奋,大多数我们都在处理不同大小的数据,使用动态bytes.Buffer共享池我们将收益巨大。

    goos: darwin
    goarch: amd64
    pkg: github.com/thinkeridea/go-extend/pool/benchmark
    BenchmarkBufferPool
    BenchmarkBufferPool-8                    1088794              1102 ns/op             387 B/op          0 allocs/op
    BenchmarkBufferSyncPool
    BenchmarkBufferSyncPool-8                  49735             37895 ns/op          115277 B/op          0 allocs/op
    BenchmarkBufferFixedSizePool
    BenchmarkBufferFixedSizePool-8          27296764                42.7 ns/op             0 B/op          0 allocs/op
    BenchmarkBufferFixedSizeSyncPool
    BenchmarkBufferFixedSizeSyncPool-8      26099842                59.6 ns/op           192 B/op          0 allocs/op
    PASS
    ok      github.com/thinkeridea/go-extend/pool/benchmark 8.627s
    
    opened by thinkeridea 1
  • exmath.Round 精度为负数时结果精准度问题 #14

    exmath.Round 精度为负数时结果精准度问题 #14

    该提交用于修复 #14 精度问题,其原因为 precision < 0 其参与计算的浮点数比较小,导致最终运算结果精度得不到保证

    分别处理 precision = 0precision <0precision > 0 的情况,以保证精准度为核心目标。

    新实现相较于旧方案性能略有下降:

    name            old time/op  new time/op  delta
    Round-8         3.45ns ± 1%  4.04ns ±14%  +17.25%  (p=0.000 n=44+46)
    RoundDecimal-8  3.47ns ± 1%  3.86ns ± 2%  +11.17%  (p=0.000 n=40+50)
    RoundInteger-8  4.38ns ± 1%  5.14ns ± 1%  +17.38%  (p=0.000 n=49+48)
    
    opened by thinkeridea 1
  • 调优exmath.Round算法

    调优exmath.Round算法

    调优 exmath.Round 算法,获得接近 16% 的性能提升

    $ benchstat old.txt new.txt

    name old time/op new time/op delta Round-8 4.20ns ± 3% 3.50ns ± 4% -16.69% (p=0.000 n=44+49)

    $ benchcmp old.txt new.txt

    benchcmp is deprecated in favor of benchstat: https://pkg.go.dev/golang.org/x/perf/cmd/benchstat benchmark old ns/op new ns/op delta BenchmarkRound-8 5.50 3.55 -35.45% BenchmarkRound-8 4.50 3.49 -22.44% BenchmarkRound-8 4.45 3.47 -22.02% BenchmarkRound-8 4.35 3.57 -17.93% BenchmarkRound-8 4.56 3.45 -24.34% BenchmarkRound-8 4.84 3.47 -28.31% BenchmarkRound-8 4.19 3.46 -17.42% BenchmarkRound-8 4.16 3.47 -16.59% BenchmarkRound-8 4.16 3.48 -16.35% BenchmarkRound-8 4.17 3.48 -16.55% BenchmarkRound-8 4.16 3.46 -16.83% BenchmarkRound-8 4.18 3.48 -16.75% BenchmarkRound-8 4.19 3.48 -16.95% BenchmarkRound-8 4.23 3.47 -17.97% BenchmarkRound-8 4.18 3.56 -14.83% BenchmarkRound-8 4.23 3.71 -12.29% BenchmarkRound-8 4.14 3.60 -13.04% BenchmarkRound-8 4.18 3.62 -13.40% BenchmarkRound-8 4.19 3.58 -14.56% BenchmarkRound-8 4.30 3.59 -16.51% BenchmarkRound-8 4.27 3.53 -17.33% BenchmarkRound-8 4.25 3.47 -18.35% BenchmarkRound-8 4.29 3.46 -19.35% BenchmarkRound-8 4.24 3.47 -18.16% BenchmarkRound-8 4.23 3.57 -15.60% BenchmarkRound-8 4.16 3.47 -16.59% BenchmarkRound-8 4.23 3.56 -15.84% BenchmarkRound-8 4.24 3.58 -15.57% BenchmarkRound-8 4.19 3.48 -16.95% BenchmarkRound-8 4.22 3.46 -18.01% BenchmarkRound-8 4.19 3.48 -16.95% BenchmarkRound-8 4.23 3.46 -18.20% BenchmarkRound-8 4.17 3.47 -16.79% BenchmarkRound-8 4.25 3.63 -14.59% BenchmarkRound-8 4.17 3.47 -16.79% BenchmarkRound-8 4.14 3.46 -16.43% BenchmarkRound-8 4.21 3.46 -17.81% BenchmarkRound-8 4.15 3.47 -16.39% BenchmarkRound-8 4.23 3.44 -18.68% BenchmarkRound-8 4.18 3.48 -16.75% BenchmarkRound-8 4.17 3.46 -17.03% BenchmarkRound-8 4.20 3.47 -17.38% BenchmarkRound-8 4.33 3.47 -19.86% BenchmarkRound-8 4.19 3.47 -17.18% BenchmarkRound-8 4.17 3.48 -16.55% BenchmarkRound-8 4.18 3.52 -15.79% BenchmarkRound-8 4.17 3.49 -16.31% BenchmarkRound-8 4.19 3.47 -17.18% BenchmarkRound-8 4.17 3.47 -16.79% BenchmarkRound-8 4.16 3.57 -14.18%

    opened by thinkeridea 1
  • 加快内网地址检查,172.16~31.0.0/12 其掩码地址均为 172.16.0.0/12 存在重复

    加快内网地址检查,172.16~31.0.0/12 其掩码地址均为 172.16.0.0/12 存在重复

    "10.0.0.0/8",
    "169.254.0.0/16",
    "172.16.0.0/12",
    "172.17.0.0/12",
    "172.18.0.0/12",
    "172.19.0.0/12",
    "172.20.0.0/12",
    "172.21.0.0/12",
    "172.22.0.0/12",
    "172.23.0.0/12",
    "172.24.0.0/12",
    "172.25.0.0/12",
    "172.26.0.0/12",
    "172.27.0.0/12",
    "172.28.0.0/12",
    "172.29.0.0/12",
    "172.30.0.0/12",
    "172.31.0.0/12",
    "192.168.0.0/16",	
    

    172.16~31.0.0/12 其掩码地址均为 172.16.0.0/12 存在重复。

    使用直接对比ip段前两段数据检查,不使用 network.Contains 判断,在暂时不支持IPV6 的前提下,这种方法更加高效。

    optimize 
    opened by thinkeridea 1
  • 改变 pool.NewBuffer 的行为,响应固定容量的BufferPool

    改变 pool.NewBuffer 的行为,响应固定容量的BufferPool

    pool.NewBuffer 在 #16 中引入的方法,实现根据实际使用场景动态评估默认 bytes.Buffer 容量的方法,因测试存在bug(在 #17 #18 中发现及修复) 后被弃用,但是考虑 BufferPool 接口可以简化使用 sync.Pool 获取及响应 bytes.Buffer实例,故通过改变 pool.NewBuffer 的行为,响应一个独立的非共享的 BufferPool,每次调用都会返回新的 BufferPool

    optimize 
    opened by thinkeridea 0
  • “动态评估bytes.Buffer的需求的容量,全局共享bytes.Buffer池” 这个pr存在性能测试问题,导致结果存在偏差

    “动态评估bytes.Buffer的需求的容量,全局共享bytes.Buffer池” 这个pr存在性能测试问题,导致结果存在偏差

    #16 在性能测试时,对SyncPool 测试时并没有对 Buffer 进行 Reset 操作,导致大量内存分配,测试结果没有参考性。

    在完善测试用例后,以下测试结果并没有相较 sync.Pool 有明显优势,且可能对性能产生影响。

    goos: darwin
    goarch: amd64
    pkg: github.com/thinkeridea/go-extend/pool/benchmark
    BenchmarkBufferPool
    BenchmarkBufferPool-8                     943312              1065 ns/op               1 B/op          0 allocs/op
    BenchmarkBufferSyncPool
    BenchmarkBufferSyncPool-8                1000000              1032 ns/op               0 B/op          0 allocs/op
    BenchmarkBufferFixedSizePool
    BenchmarkBufferFixedSizePool-8          29174670                44.1 ns/op             0 B/op          0 allocs/op
    BenchmarkBufferFixedSizeSyncPool
    BenchmarkBufferFixedSizeSyncPool-8      38488425                28.1 ns/op             0 B/op          0 allocs/op
    PASS
    ok      github.com/thinkeridea/go-extend/pool/benchmark 5.236s
    
    bug 
    opened by thinkeridea 0
  • 扩展exstrings函数

    扩展exstrings函数

    • 优化 exstrings.Reverse 方法,使其代码更加易读,并进行多种反转字符串方法性能对比,其测试代码在exstrings/benchmark/reverse_test.go, 其中BenchmarkReverseUTF8DecodeRuneInString 是优化前版本, BenchmarkExstringsReverse 是优化有版本,性能提升约3%,其结果如下:
    $ go test -benchmem -bench="Reverse"  
    goos: darwin
    goarch: amd64
    pkg: github.com/thinkeridea/go-extend/exstrings/benchmark
    BenchmarkReverseRunes-8                           703830              1700 ns/op             480 B/op          2 allocs/op
    BenchmarkReverseRange-8                          1400299               861 ns/op             192 B/op          1 allocs/op
    BenchmarkReverseUTF8DecodeRuneInString-8         1482175               717 ns/op             192 B/op          1 allocs/op
    BenchmarkExstringsReverse-8                      1698225               694 ns/op             192 B/op          1 allocs/op
    PASS
    ok      github.com/thinkeridea/go-extend/exstrings/benchmark    7.995s
    
    • 创建一个 exstrings.Bytes 方法,用来替换 []byte(s),相比 []byte(s) 转换类型提升 14%,这仅仅是一个趣味函数,性能测试代码exstrings/benchmark/convert_test.go 结果如下:
    $ go test -benchmem -bench="StringToBytes"  
    goos: darwin
    goarch: amd64
    pkg: github.com/thinkeridea/go-extend/exstrings/benchmark
    BenchmarkStandardLibraryStringToBytes-8         19118637                64.0 ns/op           192 B/op          1 allocs/op
    BenchmarkExstringsStringToBytes-8               22079703                55.1 ns/op           192 B/op          1 allocs/op
    PASS
    ok      github.com/thinkeridea/go-extend/exstrings/benchmark    4.426s
    
    • 添加 exutf8.RuneSub 别名 exbytes.Sub
    • 添加 exutf8.RuneSubString 别名 exstrings.SubString
    enhancement optimize 
    opened by thinkeridea 0
Releases(v1.3.2)
  • v1.3.2(Feb 23, 2021)

  • v1.3.1(Feb 18, 2021)

  • v1.3.0(Feb 5, 2021)

    • 修正HasLocalIPddr方法名为HasLocalIPAddr
    • 简化RemoteIP代码
    • 简化获取客户端ip逻辑
    • 增加获取基础类型指针的快写方法,主要用于字面量数据
    • 增加时间单位天和周的定义
    • 实现动态容量和全局共享的bytes.Buffer池 (#16)
    • 简化join int系列方法,采用动态容量bytes.Buffer池
    Source code(tar.gz)
    Source code(zip)
  • v1.2.2(Jan 12, 2021)

  • v1.2.1(Jan 12, 2021)

  • v1.2.0(Jan 1, 2021)

    • 迁移 travis cigithub action
    • 精简 README.md ,考虑后续迁出文档
    • 调整 go-extend 支持的最低 go 版本为 1.13
    • 添加 errno包,支持错误码、错误包装、错误格式化、友好错误评论、errors.Iserrors.As 错误检查
    • 精简 exutf8.RuneIndexexutf8.RuneIndexInString 逻辑
    • 新增 exsync.Onceexsync.OncePointer 性能无限接近 sync.Once, 比 sync.Once 更易用
    • 新增 exmath.Round,对 float64 进行四舍五入计算,支持保留小数位数及整数精度控制
    • 使用 exsync.OncePointer 改善 pool.BufferPool 实现
    • 新增 extime.ParseInLocal,快捷的解析时间到本地时区
    Source code(tar.gz)
    Source code(zip)
  • v1.1.2(Nov 3, 2020)

  • v1.1.1(Jan 6, 2020)

  • v1.1.0(Nov 4, 2019)

    • 新增 exutf8 包 #7 #8
    • 新增 exstrings.SubStringexbytes.Sub 快速截取字符串 #9
    • 新增 exstrings.Bytes[]byte(s) 转换类型效率更高 #9
    • 新增 exstrings.Copy 快速创建字符串副本,减少内存泄漏 #4
    • 优化 exstrings. Reverse #5
    Source code(tar.gz)
    Source code(zip)
  • v1.0.1(Oct 14, 2019)