LoginSignup
1
2

More than 5 years have passed since last update.

golangパフォーマンス1:文字列とビット転換

Last updated at Posted at 2016-10-25

golang 文字列とビット転換のパフォーマンス
テスト環境: go version go1.7.3 windows/amd64

ファイル構造:
rootファイル/01byteToString.go
rootファイル/01byteToString_test.go (転換効率テスト用)

01byteToString.go

package go1_6

import "unsafe"

func StringToByte(s string) []byte {
    //[]byte(s)処理はまず文字列をコピーしてbyteに転換を行う
    return []byte(s)
}

func ByteToString(b []byte) string {
    return string(b)
}

//StringToByteにより早いし 余裕メモリが利用なし
func StringToBytePerf(s string) []byte {
    //メモリで直接転換可能
    x := (*[2]uintptr)(unsafe.Pointer(&s)) //stringは静的系ためメモリ中にポインタで  x[0] : メモリスタート場所  x[1] : 長さ
    h := [3]uintptr{x[0], x[1], x[1]}      // []byteは動的ためメモリ中にポインタで x[0] : メモリスタート場所 x[1] : 実際長さ(len) x[2] : 良いした長さ(cap)
    return *(*[]byte)(unsafe.Pointer(&h))
}

//ByteToStringにより早いし 余裕メモリが利用なし
func ByteToStringPerf(b []byte) string {
    //byteポインタ直接にstirngポインタに転換(x[2]なしになる)
    return *(*string)(unsafe.Pointer(&b))
}

01byteToString_test.go

package go1_6

import (
    "github.com/stretchr/testify/assert"
    "testing"
)

const StringTest = "hello, world!"

func TestStringToByte(t *testing.T) {
    assert.Equal(t, StringToByte(StringTest), []byte(StringTest))
}

func TestByteToString(t *testing.T) {
    assert.Equal(t, ByteToString([]byte(StringTest)), StringTest)
}

func BenchmarkStringToByte(b *testing.B) {
    for i := 0; i < b.N; i++ {
        StringToByte(StringTest)
    }
}

func BenchmarkByteToString(b *testing.B) {
    for i := 0; i < b.N; i++ {
        ByteToString([]byte(StringTest))
    }
}

//---------------------------------------------------------------------

func TestStringToBytePerf(t *testing.T) {
    assert.Equal(t, StringToBytePerf(StringTest), []byte(StringTest))
}

func TestByteToStringPerf(t *testing.T) {
    assert.Equal(t, ByteToStringPerf([]byte(StringTest)), StringTest)
}

func BenchmarkStringToBytePerf(b *testing.B) {
    for i := 0; i < b.N; i++ {
        StringToBytePerf(StringTest)
    }
}

func BenchmarkByteToStringPerf(b *testing.B) {
    for i := 0; i < b.N; i++ {
        ByteToStringPerf([]byte(StringTest))
    }
}

テスト結果:
image
ポイント:
string構造:[3]uintptr{x[0], x[1], x[2]}
[]byte構造:[2]uintptr{x[0], x[1]}
デメリット:
変数のポインタが変わります。(使い場合は用注意)

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2