Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Reflectionのパフォーマンス

  • Be the first to comment

Reflectionのパフォーマンス

  1. 1. Reflectionの パフォーマンス © 2015 sprout Inc. All Rights Reserved. 1 株式会社スプラウト 高橋 明 Twitter : @Talos208
  2. 2. Goは静的型付けのコンパイル言語 • 実行時にはソースの情報は(基本)なくなる • コンパイル時になるべく処理してしまう • 実行時の処理が減り、パフォーマンスは比較的高い • どうしても欲しい場面があるので、一部だけ取得できる • Reflection • わざわざReflectionしてしまうと遅くなるのでは? • 測定してみよう © 2015 sprout Inc. All Rights Reserved. 2
  3. 3. Reflectionの使用方法 • reflectパッケージ • 型の取得 • reflect.TypeOf() • 一部の型については、より多くの情報が取れる • struct • メンバ/メソッドの個数/一覧 • タグ • func • 引数/返り値の個数/一覧 © 2015 sprout Inc. All Rights Reserved. 3
  4. 4. Reflectionの使用方法 • 動的な値の変更 © 2015 sprout Inc. All Rights Reserved. 4 func sub(v interface{}) { p := reflect.ValueOf(v) switch v.(type) { case float64: p.Elem().SetFloat(p.Elem().Float() * 2) case string: p.Elem().SetString(p.Elem().String() + p.Elem().String()) } } func main() { var x float64 = 3.14 sub(&x) var s string = "fuga" sub(&s) log.Print(x, s) }
  5. 5. Reflectionを使いたくなる場面 • 型のない世界とのインターフェース • 文字列出力 • SQL • シリアライズ/デシリアライズ • メタプログラミング • structの各メンバにアクセサを作る • 引数によるオーバーロード • C++脳、Ruby脳だと、ついそういうインターフェースにしてし まう © 2015 sprout Inc. All Rights Reserved. 5
  6. 6. Reflectionはどこからデータを取る? • The Laws of Reflection - The Go Blog • interface{}は2つの要素を持つ • 値そのもの • 型情報 ↓ • reflect.ValueOf() • reflect.TypeOf() • 元から値を持っている • Reflectionしても速度低下は少なそう © 2015 sprout Inc. All Rights Reserved. 6
  7. 7. 実例:複数の引数パターンをもつ関数 func A(arg ...interface{}) error { if len(arg) == 1 { log.Print("index only.") } else if len(arg) == 2 { log.Print("`tbl`[index].") } else { return errors.New("Illigal arguments") } return nil } © 2015 sprout Inc. All Rights Reserved. 7 1.引数の個数で切り替え
  8. 8. 実例:複数の引数パターンをもつ関数 func B(arg ...interface{}) error { switch arg[0].(type) { case string: log.Print("`tbl`[index].") case int: log.Print("index only.") default: return errors.New("Illigal arguments") } return nil } © 2015 sprout Inc. All Rights Reserved. 8 2.Type switch
  9. 9. 実例:複数の引数パターンをもつ関数 func C(arg ...interface{}) error { switch reflect.TypeOf(arg[0]).Kind() { case reflect.String: log.Print("`tbl`[index].") case reflect.Int: log.Print("index only.") default: return errors.New("Illigal arguments") } return nil } © 2015 sprout Inc. All Rights Reserved. 9 3.Reflection
  10. 10. 測定結果 © 2015 sprout Inc. All Rights Reserved. 10 回数 A B C 0 0.00 0.00 0.00 100000 351.36 363.25 347.39 200000 702.43 721.07 694.58 300000 1054.65 1078.86 1037.19 400000 1418.24 1437.43 1379.34 500000 1778.74 1795.08 1720.92 600000 2139.28 2151.77 2065.88 700000 2498.37 2508.04 2408.76 800000 2860.89 2868.46 2753.47 900000 3218.83 3220.60 3100.67 1000000 3578.66 3572.59 3445.14
  11. 11. 測定結果 © 2015 sprout Inc. All Rights Reserved. 11 0 500 1000 1500 2000 2500 3000 3500 4000 0 10000 20000 30000 40000 50000 60000 70000 80000 90000 100000 実行時間(ms) 実行回数 A B C
  12. 12. まとめ • Goのリフレクションのパフォーマンスは十分高い • リフレクションが必要な場面では、変なHackをせずにリ フレクションを使って構わない © 2015 sprout Inc. All Rights Reserved. 12

×