據說,這反映的一些地方不執行得非常好。這是真的,它的哪些部分被認爲表現緩慢?
背景:我目前正在嘗試使用反射的自寫持久層。我還沒有做過測量。我只需要知道可能的優化點位置,以便我可以很好地設計程序。
據說,這反映的一些地方不執行得非常好。這是真的,它的哪些部分被認爲表現緩慢?
背景:我目前正在嘗試使用反射的自寫持久層。我還沒有做過測量。我只需要知道可能的優化點位置,以便我可以很好地設計程序。
大多數使用反射緩存的框架都會反射操作的結果,以便它們不必再次執行它們。所以事實上,一切都會在啓動時發生。
除此之外 - 所有零件都是「不合格的」。常規代碼應避免使用全反射API。對於框架 - 請參閱第1段。
你將如何緩存對象的反射創建,例如Object c = klass.newInstance()? – 2011-01-21 00:51:26
@Pangea - 當然創建不能被緩存。但所有其他元數據是。 – Bozho 2011-01-21 06:47:29
典型的方法調用效果很好。性能問題可能是由Class.getMethod()
,Class.getField()
,Class.getDeclaredMethod()
等引起的。Class.forName()
也很慢(雖然它比動態類加載要比反射)。
因此,我建議您緩存方法定位方法的結果,例如,
Method m = Class.getMethod("foo"); // do it once
// now invoke it as many times as you want
m.invoke(obj);
整個思考點是爲了繞開類型系統去做語言從來沒有打算做的事情。所以無論你做什麼都會很慢。
Reflection允許您權衡性能以獲得更簡單的解決方案,這些解決方案可以更快速地編寫並保持更輕鬆。只要你發現自己用反射來使你的代碼複雜化,你就會犯錯誤。
更新
通過 「簡單」,我的意思是較少的代碼行。基本上較短的解決方案反射使您可以放棄類型安全來編寫一個更簡短,更簡潔的程序。這是動態打字背後的理性。 Java泛型給你一個更復雜的程序,但你有類型安全。反射使您可以動態地輸入靜態類型的語言。我的觀點是,如果程序的「反射」版本比等效的「非反射」版本更復雜,那麼非反射版本會更好,因爲它運行速度更快,並且更簡單。
反射還有其他用途,但元編程並不是真正的其中之一。元編程是編寫寫另一個程序的程序的地方。例如,假設您想重新格式化一大組文件的名稱;也許是一組婚紗照。一個程序來做到這一點,我看起來像這樣:
mv "1bill and fred(kfjw0f3).jpg" "1 - bill and fred.jpg"
mv "2sam and kim(g02fsgsg).jpg" "2 - sam and kim.jpg"
.
.
.
生成該mv命令列表的Ruby程序將是一個元程序。
速度大都歸結爲多少條指令需要處理器
上執行(過於簡單化,但讓我們與它運行第二次)。
當您調用方法時,代碼可以進行JIT編譯,從而使開銷最小化。你已經知道要調用什麼方法,因此你知道你是否以有效的方式調用它,返回什麼,它需要什麼代碼等。
當你用反射做這件事時,一切都會消失窗戶。你必須嘗試用一個字符串來查找方法,然後看看你是否正確調用它,然後獲取所有代碼並運行它。通常情況下,這些都不能預先完成。
這又回到了靜態和動態的區別:
靜態:快,一切已知的早期,在執行時所需的最少的努力。
動態:慢,事情稍後纔會出現,所以事情必須在運行時完成。
這並不意味着反射是'壞'!!!!!!!!速度是不是所有和最終所有!!!!!
如果它節省了時間並使事情變得簡單:做到這一點!如果您後來發現您需要更好的性能,並且反射率在大約80%的時間內運行約20%,那麼請考慮一些其他解決方案。如果是這樣,Java將是一種非常不同的語言,你可能幾乎不會使用對象。顯然,你應該記住速度,並且有一些關於反思的知識,這正是你問這個問題的原因。 :D
別擔心。它非常快。特別是與數據庫操作相比。
像使用運行時字節碼生成一樣的持久性框架中的優化是非常奇怪的。我們在這裏談論數據庫......只是使用反射。
PS:一個很好的初步認識和博客文章中,今天出版
http://buzdin.blogspot.com/2011/01/is-java-reflection-really-slow.html
而不是創建自己的持久層,你可能要考慮向許多開源的一個。 – 2011-01-20 22:39:45
反思比較慢....什麼?你有什麼其他機制與內省類和對象進行比較? – Xailor 2011-01-20 22:43:38