以前看到許多網友認為靜態方法要比實例方法在執行效率上要快一些,當初不敢茍同。自己親自試了一把,發現靜態方法確實要快一些。
想要比較靜態方法與非靜態方法的執行效率,需要對CLR在調用靜態方法與非靜態方法時的不同之處要有一個了解。
靜態方法是與類相關聯的,CLR在調用一個靜態方法時需要做的事情就是找到定義該方法的類型即可實現調用;而在調用非靜態方法時,為了保證運行安全,CLR會對我們的源代碼進行驗證并額外的生成一些IL中間代碼來確保運行安全,所以在調用一個非靜態方法時,CLR首先是判定被調用對象是否為NULL,如果為NULL,則引發一個異常,反之,則根據對象推薦出其類型,最后實現調用??梢钥闯鰜恚谡{用靜態方法來非靜態方法時,后者比前者多做了一些工作,這將造成性能上的損失。所以,靜態方法在執行效率上可能要比非靜態方法要好一些。IL中可以看到非靜態方法執行的是callvirt 指令:

CLR via C#的解釋:調用一個靜態方法時,CLR會定位與定義靜態方法的類型對應的類型對象。然后,JIT編譯器在類型對象的方法表中查找與被調用的方法對應的記錄項,對方法進行JIT編譯(如果需要的話),再調用JIT編譯的代碼。過程圖如下:

一般情況下聲明靜態方法的類大多是工具類,并且這些靜態方法不需要訪問類型中的非靜態字段和事件,也就是說靜態方法與該類型中的非靜態字段和事件不具有邏輯上的關聯性。如果一個方法聲明為靜態方法,也意味著不能被重寫,該方法失去面向對象的擴展和多態的特性。
總結:靜態方法與實例方法在性能和占用內存上沒有明顯的區別,是否聲明為靜態方法需要從類型的非靜態字段、事件、面向對象擴展和多態這三方面來考慮。
新聞熱點
疑難解答