Upgrade to Pro — share decks privately, control downloads, hide ads and more …

今更だけどGob

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.

 今更だけどGob

Jun 21 2017 CA.go

Avatar for Shun Kokubo

Shun Kokubo

June 22, 2017
Tweet

Other Decks in Technology

Transcript

  1. KVS? File? // bolt/boltdb db.Update(func(tx *bolt.Tx) error { b :=

    tx.Bucket([]byte("anyBucket")) err := b.Put([]byte("key"), []byte("value")) return nil }) // syndtr/goleveldb err = db.Put([]byte("key"), []byte("value"), nil) // allegro/bigcache cache.Set("key", []byte("value")) そこでGob
  2. 使い方 var buf bytes.Buffer enc := gob.NewEncoder(&buf) dec := gob.NewDecoder(&buf)

    e := Data{ ID: "test_id", Num: 100, } var d Data enc.Encode(e) dec.Decode(&d) fmt.Printf("%+v", d) Run
  3. 使い方 var buf bytes.Buffer enc := gob.NewEncoder(&buf) dec := gob.NewDecoder(&buf)

    var e int e = 100 var d int enc.Encode(e) dec.Decode(&d) fmt.Println(d) Run
  4. 定義不要 type wireType struct { ArrayT *arrayType SliceT *sliceType StructT

    *structType MapT *mapType GobEncoderT *gobEncoderType BinaryMarshalerT *gobEncoderType TextMarshalerT *gobEncoderType }
  5. 定義不要 type CommonType struct { Name string Id int }

    type arrayType struct { CommonType Elem typeId Len int } type sliceType struct { CommonType Elem typeId } type structType struct { CommonType Field []*fieldType } type fieldType struct { Name string Id int } 全てName とID を持つCommonType を埋め込みで持つ
  6. Self describing type Example struct { ID string Num int

    Value interface{} } Example というType を定義すると binary に定義情報が含まれる ("define type id" 256, definition of type Example)(256, Example value)...
  7. Self describing 実際のbinary もこの様な形となる $ hexdump -C example.bin 00000000 2e

    ff 81 03 01 01 07 45 78 61 6d 70 6c 65 01 ff |.......Example..| 00000010 82 00 01 03 01 02 49 44 01 0c 00 01 03 4e 75 6d |......ID.....Num| 00000020 01 04 00 01 05 56 61 6c 75 65 01 10 00 00 00 22 |.....Value....."| 00000030 ff 82 01 0a 65 78 61 6d 70 6c 65 5f 69 64 01 ff |....example_id..| 00000040 c8 01 06 73 74 72 69 6e 67 0c 06 00 04 74 65 73 |...string....tes| 00000050 74 00 |t.| 00000052 CommonType を含むwireType によって表現される 各type のID と eld 情報
  8. 構造変更が可能 type Src struct { ID string Score float64 Num

    int } type Dest struct { ID *string Score float32 Order int } encode,decode 側のtype, eld が違っても
  9. 構造変更が可能 値の扱われ方に特徴がある var buf bytes.Buffer enc := gob.NewEncoder(&buf) dec :=

    gob.NewDecoder(&buf) s := Src{ ID: "test_id", Num: 100, Score: 1.23, } var d Dest enc.Encode(s) dec.Decode(&d) fmt.Printf("%+v\n", d) fmt.Println(*d.ID) Run
  10. ベンチで比較 type Data struct { Str string Int int64 Float

    float64 Bool bool } type Encoder interface { Encode(interface{}) error } type Decoder interface { Decode(interface{}) error }
  11. ベンチで比較 func benchEncode(buf *bytes.Buffer, enc Encoder, b *testing.B) { b.ResetTimer()

    for i := 0; i < b.N; i++ { buf.Reset() err := enc.Encode(encodeData) if err != nil { b.Fatal(err) } } }
  12. ベンチで比較 func benchDecode(buf *bytes.Buffer, enc Encoder, dec Decoder, b *testing.B)

    { var e Data b.ResetTimer() for i := 0; i < b.N; i++ { b.StopTimer() buf.Reset() err := enc.Encode(encodeData) if err != nil { b.Fatal(err) } b.StartTimer() err = dec.Decode(&e) if err != nil { b.Fatal(err) } } }
  13. ベンチで比較 func BenchmarkGobEncode(b *testing.B) { var buf bytes.Buffer enc :=

    gob.NewEncoder(&buf) benchEncode(&buf, enc, b) } func BenchmarkJsonEncode(b *testing.B) { var buf bytes.Buffer enc := json.NewEncoder(&buf) benchEncode(&buf, enc, b) }
  14. ベンチで比較 func BenchmarkGobDecode(b *testing.B) { var buf bytes.Buffer enc :=

    gob.NewEncoder(&buf) dec := gob.NewDecoder(&buf) benchDecode(&buf, enc, dec, b) } func BenchmarkJsonDecode(b *testing.B) { var buf bytes.Buffer enc := json.NewEncoder(&buf) dec := json.NewDecoder(&buf) benchDecode(&buf, enc, dec, b) }
  15. ベンチで比較 $ go test -benchmem -bench . BenchmarkGobEncode-8 2000000 642

    ns/op 48 B/op 1 allocs/op BenchmarkJsonEncode-8 2000000 946 ns/op 56 B/op 2 allocs/op BenchmarkGobDecode-8 1000000 1425 ns/op 16 B/op 1 allocs/op BenchmarkJsonDecode-8 500000 3299 ns/op 48 B/op 3 allocs/op
  16. 注意点 interface を扱う時は… type Handler interface { GetID() string }

    type A struct { ID string } func (a *A) GetID() string { return a.ID }
  17. 注意点 最初にRegister func main() { var buf bytes.Buffer enc :=

    gob.NewEncoder(&buf) dec := gob.NewDecoder(&buf) var e Handler e = &A{ ID: "A", } fmt.Println(enc.Encode(&e)) var d Handler fmt.Println(dec.Decode(&d)) fmt.Println(d.GetID()) } Run
  18. 注意点 ポインターで渡す func init() { gob.Register(&A{}) } func main() {

    var buf bytes.Buffer enc := gob.NewEncoder(&buf) dec := gob.NewDecoder(&buf) var e Handler e = &A{ ID: "A", } fmt.Println(enc.Encode(e)) var d Handler fmt.Println(dec.Decode(&d)) fmt.Println(d.GetID()) } Run
  19. 注意点 func init() { gob.Register(&A{}) } func main() { var

    buf bytes.Buffer enc := gob.NewEncoder(&buf) dec := gob.NewDecoder(&buf) var e Handler e = &A{ ID: "A", } fmt.Println(enc.Encode(&e)) var d Handler fmt.Println(dec.Decode(&d)) fmt.Println(d.GetID()) } Run