有人可以解釋使用反射包訪問結構字段時的性能差異,如下所示: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當前的實現有一個帶有字符串相等性測試的線性掃描。我們必須至少測試每個字符串一次,對于長度匹配的字符串,我們還必須對單個字符串字節進行額外的測試,至少直到它們不匹配為止。
- 1 回答
- 0 關注
- 96 瀏覽
添加回答
舉報
0/150
提交
取消