寝ても覚めてもこんぴうた

プログラム書いたり、ネットワーク設計したり、サーバ構築したり、車いじったり、ゲームしたり。そんなひとにわたしはなりたい。 投げ銭は kyash_id : chidakiyo マデ

忘れがちなGoでbyteをstringに変換する方法をベンチマークしてみた。

golangでbyteをstringに変換する処理はたびたび発生するのですが、 手抜きで fmt.Sprintf("%s", byte) などとやっちゃうこともあるのでそれぞれの書き方でどれが速いのか確認してみた。

1) Sprintfを使うパターン

fmt.Sprintf("%s", data)

2) string() を使うパターン

string(data)

3) unsafe を使うパターン

*(*string)(unsafe.Pointer(&data))

唐突にテストコード

package main

import (
    "fmt"
    "unsafe"
    "testing"
)

var data  = []byte("はろーhogehogeです。")

func Benchmark_Sprintf(b *testing.B){
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        _ = fmt.Sprintf("%s", data)
    }
}

func Benchmark_String(b *testing.B){
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        _= string(data)
    }
}

func Benchmark_Unsafe(b *testing.B){
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        _ = *(*string)(unsafe.Pointer(&data))
    }
}

実行して試してみる

go test -bench . -benchmem

結果

Benchmark_Sprintf-4     10000000               164 ns/op              64 B/op          2 allocs/op
Benchmark_String-4      200000000                9.88 ns/op            0 B/op          0 allocs/op
Benchmark_Unsafe-4      2000000000               0.37 ns/op            0 B/op          0 allocs/op
PASS
ok      bitbucket.org/chidakiyo/devnule/sandbox 5.555s

3) unsafe を使うパターン

*(*string)(unsafe.Pointer(&data))

が一番速いようですね。スッキリ!