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))
が一番速いようですね。スッキリ!