dpzo13732 2017-10-20 12:15
浏览 119
已采纳

将字符串转换为二进制的字符串表示的有效方法

I'm searching how to convert a string to a string representation in binary with best performance.

So I started with something similar to the following:

func binConvertOrig(s string) string {
    var buf bytes.Buffer
    for i := 0; i < len(s); i++ {
        fmt.Fprintf(&buf, "%08b", s[i])
    }
    return buf.String()
}

s := "Test"
log.Printf("%s => binConvertOrig => %s", s, binConvertOrig(s))

But it seems that fmt.Fprintf & bytes.Buffer are not very efficient.

Is there a better way to do this?

Thanks

  • 写回答

1条回答 默认 最新

  • dsa5233 2017-10-20 12:22
    关注

    Nothing beats a pre-calculated lookup table, especially if it's stored in a slice or array (and not in a map), and the converter allocates a byte slice for the result with just the right size:

    var byteBinaries [256][]byte
    
    func init() {
        for i := range byteBinaries {
            byteBinaries[i] = []byte(fmt.Sprintf("%08b", i))
        }
    }
    
    func strToBin(s string) string {
        res := make([]byte, len(s)*8)
        for i := len(s) - 1; i >= 0; i-- {
            copy(res[i*8:], byteBinaries[s[i]])
        }
        return string(res)
    }
    

    Testing it:

    fmt.Println(strToBin("\x01\xff"))
    

    Output (try it on the Go Playground):

    0000000111111111
    

    Benchmarks

    Let's see how fast it can get:

    var texts = []string{
        "\x00",
        "123",
        "1234567890",
        "asdf;lkjasdf;lkjasdf;lkj108fhq098wf34",
    }
    
    func BenchmarkOrig(b *testing.B) {
        for n := 0; n < b.N; n++ {
            for _, t := range texts {
                binConvertOrig(t)
            }
        }
    }
    
    func BenchmarkLookup(b *testing.B) {
        for n := 0; n < b.N; n++ {
            for _, t := range texts {
                strToBin(t)
            }
        }
    }
    

    Results:

    BenchmarkOrig-4      200000     8526 ns/op       2040 B/op     12 allocs/op
    BenchmarkLookup-4   2000000      781 ns/op        880 B/op      8 allocs/op
    

    The lookup version (strToBin()) is 11 times faster and uses less memory and allocations. Basically it only uses allocation for the result (which is unavoidable).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 求chat4.0解答一道线性规划题,用lingo编程运行,第一问要求写出数学模型和lingo语言编程模型,第二问第三问解答就行,我的ddl要到了谁来求了
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥15 maple软件,用solve求反函数出现rootof,怎么办?
  • ¥65 汇编语言除法溢出问题
  • ¥15 Visual Studio问题
  • ¥20 求一个html代码,有偿
  • ¥100 关于使用MATLAB中copularnd函数的问题
  • ¥20 在虚拟机的pycharm上
  • ¥15 jupyterthemes 设置完毕后没有效果