亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用反射訪問結構字段(作為字符串變量)與直接訪問它的性能

使用反射訪問結構字段(作為字符串變量)與直接訪問它的性能

Go
梵蒂岡之花 2022-10-10 19:57:43
有人可以解釋使用反射包訪問結構字段時的性能差異,如下所示:v := reflect.ValueOf(TargetStruct) f := reflect.Indirect(v).FieldByName("Field")VS使用正常方式:f := TargetStruct.Field我之所以問,是因為我無法找到有關實際性能的資源。我的意思是,如果直接訪問(示例 2)是 O(1),那么間接訪問(示例 1)的速度是多少?還有另一個因素需要考慮,期望代碼不那么干凈并且編譯器缺少一些信息,比如字段的類型等?
查看完整描述

1 回答

?
收到一只叮咚

TA貢獻1821條經驗 獲得超5個贊

反射慢得多,即使兩個操作都是 O(1),因為大 O 表示法故意不捕獲常數,并且反射有一個很大的常數(它c大約是 100,或 2 個十進制數量級,這里)。

我會稍微(但只是輕微地)對Volker 的評論說反射O(1),因為這個特定的反射必須在運行時查找名稱,這可能涉及也可能不涉及使用 Go map,1本身未指定:請參閱golang中map的Big O表現如何? 此外,正如該問題的已接受答案中所述,無論如何,對于字符串,哈希查找并不是完全 O(1)。但同樣,這一切都被反射的常數因素所淹沒。

形式的操作:

f := TargetStruct.Field

通常會編譯成一條機器指令,根據緩存命中情況,它可以在從一個時鐘周期的一小部分到幾個周期或更多周期的任何地方運行。一種形式:

v := reflect.ValueOf(TargetStruct)
f := reflect.Indirect(v).FieldByName("Field")

變成調用運行時:

  • 分配一個新的反射對象來存儲v

  • 檢查v(在 中Indirect(),看是否Elem()有必要),然后結果Indirect()是 astruct并且有一個字段,其名稱是給定的,并獲得該字段

并且此時您仍然只有一個reflect.Value對象 in f,因此如果您想要整數,您仍然必須找到實際值:

fv := int(Field.Int())

例如。這可能是從幾十條指令到幾百條指令的任何地方。這就是我c ≈ 100猜到的地方。


1當前的實現有一個帶有字符串相等性測試的線性掃描。我們必須至少測試每個字符串一次,對于長度匹配的字符串,我們還必須對單個字符串字節進行額外的測試,至少直到它們不匹配為止。


查看完整回答
反對 回復 2022-10-10
  • 1 回答
  • 0 關注
  • 96 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號