儘管反射(reflect)存在性能問題,但依然被頻繁使用,以彌補靜態語言在動態行爲上的不足。只是某些時候,咱們須對此作些變通,以提高性能。緩存
爲便於閱讀,如下示例均作了最大程度精簡。安全
若是是 reflect.Type,可將其緩存,避免重複操做耗時。但 Value 顯然不行,由於它和具體對象綁定,內部存儲實例指針。換個思路,字段相對於結構,除名稱(name)外,還有偏移量(offset)這個惟一屬性。利用偏移量,將 FieldByName 變爲普通指針操做,就能夠實現性能提高。性能優化
測試一下優化成果。性能
效果很好,不是嗎?剩餘的問題是,如何設計緩存結構,這個 offset 變量天然不能用於實際開發。單元測試
用 map[Type]map[name]offset?顯然不行。每次執行 reflect.TypeOf,這於性能優化不利。可除了 Type,還有什麼能夠做爲 Key 使用?要知道,接口由 itab 和 data 指針組成,相同類型(接口和實際類型組合)的 itab 指針相同,天然也可看成 key 來用。測試
雖因引入 map 致使性能有所降低,但相比直接使用 reflect 仍是提高不少。優化
利用指針類型轉換實現性能優化,本就是 「很是手段」,是一種爲了性能而放棄 「其餘」 的作法。與其擔憂代碼是否適應將來的變化,不如寫個單元測試,確保在升級時作出必要的安全檢查。還有,本優化系列,僅僅提供一種優化思路,未必要照抄。spa
最新動態,請掃碼關注
設計