dongtuota3633 2017-10-20 23:06
浏览 741
已采纳

将int转换为十六进制字符串,然后在Golang中用0填充的有效方法?

I'm trying to convert 10 millions of int to Hex, then, padding it with 0's in order to get a 4 characters string which represents the Hex number.

So far, I tried the following:

var hexNumber string
for idx := O; idx < 10000000; idx++ {
    hexNumber = fmt.Sprintf("%04x", idx)

    // Do some stuff ....
}

But fmt.Sprintf is not very efficient. How can I achieve this in a efficient way?

Solution: It turns out that @peterSO strconv.AppendInt solution is way faster.

package bench

import (
    "fmt"
    "strconv"
    "strings"
    "testing"
)

var stringHex [16]string
var runesHex [16]rune

func init() {
    stringHex = [16]string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"}
    runesHex = [16]rune{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}
}

func intToHex1(intNumber int) string {
    hexNumber := []rune("0000")
    for i, j := int(0), uint(12); i < 4; i, j = i+1, j-4 {
        hexNumber[i] = runesHex[(intNumber>>j)&0x0f]
    }
    return string(hexNumber)
}

func intToHex2(intNumber int) string {
    hexNumber := "0000"
    for i, j := int(0), uint(12); i < 4; i, j = i+1, j-4 {
        hexNumber = hexNumber[:i] + stringHex[(intNumber>>j)&0x0f] + hexNumber[i+1:]
    }
    return hexNumber
}

func BenchmarkFmtSprintf(b *testing.B) {
    b.ReportAllocs()
    for n := 0; n < b.N; n++ {
        hexNumber := fmt.Sprintf("%04x", n)
        _ = hexNumber
    }
}

func BenchmarkStrconvFormatInt(b *testing.B) {
    b.ReportAllocs()
    for n := 0; n < b.N; n++ {
        retStr := strings.Repeat("0", 4) + strconv.FormatInt(int64(n), 16)
        hexNumber := retStr[(len(retStr) - 4):]
        _ = hexNumber
    }
}

func BenchmarkAppend(b *testing.B) {
    b.ReportAllocs()
    buf := []byte{'0', '0', '0', '0', 4 + 16: 0}
    for n := 0; n < b.N; n++ {
        buf = strconv.AppendInt(buf[:4], int64(n), 16)
        hexNumber := string(buf[len(buf)-4:])
        _ = hexNumber
    }
}

func BenchmarkIntToHex1(b *testing.B) {
    b.ReportAllocs()
    for n := 0; n < b.N; n++ {
        hexNumber := intToHex1(n)
        _ = hexNumber
    }
}

func BenchmarkIntToHex2(b *testing.B) {
    b.ReportAllocs()
    for n := 0; n < b.N; n++ {
        hexNumber := intToHex2(n)
        _ = hexNumber
    }
}

So the benchmark:

BenchmarkFmtSprintf-2            3000000               364 ns/op              16 B/op          2 allocs/op
BenchmarkStrconvFormatInt-2      5000000               354 ns/op              15 B/op          3 allocs/op
BenchmarkAppend-2               20000000                75.6 ns/op             0 B/op          0 allocs/op
BenchmarkIntToHex1-2            10000000               162 ns/op               8 B/op          1 allocs/op
BenchmarkIntToHex2-2             3000000               536 ns/op              16 B/op          4 allocs/op

展开全部

  • 写回答

2条回答 默认 最新

  • dongshanxiao7328 2017-10-21 01:09
    关注

    strconv.AppendUint appears to be faster than fmt.Sprintf. For example,

    hex_test.go:

    package main
    
    import (
        "fmt"
        "strconv"
        "testing"
    )
    
    func BenchmarkFmtSprintf(b *testing.B) {
        b.ReportAllocs()
        for n := 0; n < b.N; n++ {
            hexNumber := fmt.Sprintf("%04x", n&0xFFFF)
            _ = hexNumber
        }
    }
    
    func BenchmarkAppend(b *testing.B) {
        b.ReportAllocs()
        for n := 0; n < b.N; n++ {
            buf := []byte{'0', '0', '0', 3 + 4: 0}
            buf = strconv.AppendUint(buf[:3], uint64(n)&0xFFFF, 16)
            hexNumber := string(buf[len(buf)-4:])
            _ = hexNumber // Do some stuff ....
        }
    }
    

    Output:

    $ go test -bench=. hex_test.go
    BenchmarkSprintf-4      10000000       116 ns/op      16 B/op     1 allocs/op
    BenchmarkAppend-4       100000000       19.2 ns/op     0 B/op     0 allocs/op
    

    展开全部

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)
编辑
预览

报告相同问题?

悬赏问题

  • ¥15 盘古气象大模型调用(python)
  • ¥15 传人记程序做的plc 485从机程序该如何写
  • ¥15 已知手指抓握过程中掌指关节、手指各关节和指尖每一帧的坐标,用贝塞尔曲线可以拟合手指抓握的运动轨迹吗?
  • ¥50 libwebsockets 如何添加其他socket事件回调
  • ¥50 实现画布拖拽算子排布,通过flink实现算子编排计算,请提供思路
  • ¥15 esium自定义材质拉伸问题
  • ¥15 cmake+mingw使用<mysqlx/xdevapi.h>报错
  • ¥15 eNSP中防火墙的使用
  • ¥15 关于#mlnet#的问题:mlnet相关请求(语言-c#)
  • ¥15 lvgl7.11怎么做出文字被选中的效果
手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部