Maneira eficiente de converter um int em string hexadecimal e preenchê-lo com zeros em Golang?

LeMoussel:

Estou tentando converter 10 milhões de inteiros em hexadecimais, preenchendo-os com zeros para obter uma string de 4 caracteres que representa o número hexadecimal.

Até agora, tentei o seguinte:

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

    // Do some stuff ....
}

Mas fmt.Sprintfnão é muito eficiente. Como posso conseguir isso de forma eficiente?

Solução: Acontece que a strconv.AppendIntsolução @peterSO é muito mais rápida.

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
    }
}

Portanto, o 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
PeterSO:

strconv.AppendUintparece ser mais rápido do que fmt.Sprintf. Por exemplo,

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 ....
    }
}

Resultado:

$ 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

Este artigo é coletado da Internet.

Se houver alguma infração, entre em [email protected] Delete.

editar em
0

deixe-me dizer algumas palavras

0comentários
loginDepois de participar da revisão

Artigos relacionados

A maneira mais eficiente de converter um [] [] byte em [] string em golang

é uma maneira de converter um int em binário e colocá-lo em um array

Qual é a maneira mais eficiente de converter um int em uma String?

A maneira mais eficiente de formatar uma string em escala com zeros à esquerda e uma vírgula em vez de um ponto decimal

Incapaz de encontrar String em um arquivo e preenchê-lo usando o Inno Setup?

C # converter int em string com zeros de preenchimento?

Maneira eficiente de gerar uma string hexadecimal aleatória de comprimento fixo em Golang?

Como pegar o valor hexadecimal entre um monte de zeros e convertê-lo em decimal?

A maneira mais eficiente de converter String em Inteiro em java

Java - a maneira mais eficiente de converter um TreeSet <String> em uma String []?

Qual é a maneira mais eficiente de converter uma string curta em um inteiro de 32 bits?

Maneira mais eficiente de converter um único char em CharSequence

A maneira mais eficiente de converter um DataTable em CSV

Maneira mais eficiente de substituir zeros por uns e uns por zeros em uma string (por exemplo, "100001" a "011110")

Converter uma lista python em string com vírgulas separadas de maneira eficiente

Converter string hexadecimal em int em Python

Maneira eficiente de converter long para String em Java

maneira mais eficiente de converter vetor char em string

Como obter um intervalo de bits de uma string hexadecimal e convertê-lo em um inteiro?

Como converter um int em uma string hexadecimal?

Kotlin: converter uma string em Byte Array e preenchê-la com 0's

Converter um substring char em um int a partir de um valor de string e, em seguida, atribuí-lo a uma variável int

Como converter um endereço Mac em hexadecimal e passá-lo para um bytearray em java

Maneira eficiente de unir um dataframe Spark em cache com outro e armazenar em cache novamente

Converta um Long / ULong em uma string hexadecimal sem sinal com zeros de preenchimento

Uma maneira eficiente e eficaz de substituir valores em uma string com base no contexto em PHP

Converta uma string de uns e zeros em hexadecimal

Maneira mais eficiente de comparar um inteiro de string com um intervalo em C #

maneira eficiente de converter str em inteiros