我只是在尋找一個例子,而在它我看到的代碼的IntPtr投與新
return new IntPtr(handle);
各地的我們的代碼戳後,我發現,我們已經使用了類似的模式,但在我們的代碼我們有幾乎相同的東西:
return (IntPtr)handle;
這兩個需要有區別嗎?第二個會以任何方式「更好」,因爲它沒有分配新的內存,或者只是在下面隱藏了相同的構造函數?
我只是在尋找一個例子,而在它我看到的代碼的IntPtr投與新
return new IntPtr(handle);
各地的我們的代碼戳後,我發現,我們已經使用了類似的模式,但在我們的代碼我們有幾乎相同的東西:
return (IntPtr)handle;
這兩個需要有區別嗎?第二個會以任何方式「更好」,因爲它沒有分配新的內存,或者只是在下面隱藏了相同的構造函數?
在你的例子中,我猜句柄是一個整數值? IntPtr的聲明從的Int32(int)和Int64的(長)顯式轉換簡單地調用相同的構造函數:
public static explicit operator IntPtr(int value)
{
return new IntPtr(value);
}
所以有有力的可讀性可以關注其他的沒有什麼區別。
由於IntPtr
是一個值類型,使用new
不分配任何內存。
從技術上講,調用仍然編譯爲不同的IL - 一個實際調用構造函數,另一個調用顯式轉換運算符。然而,我不確定這兩者之間在JIT通過後是否有任何實際差異 - 很可能沒有(儘管我懷疑您在實踐中會注意到這兩種方式,這是femtooptimization)。
在任何情況下,演員比使用構造函數更習慣用法,所以我建議單獨使用它。
Reflector說,中投反正調用引擎蓋下的構造:
[Serializable, StructLayout(LayoutKind.Sequential), ComVisible(true)]
public struct IntPtr : ISerializable
{
...
[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
public static explicit operator IntPtr(int value)
{
return new IntPtr(value);
}
}
所以這個帖子是空談,沒有號碼,以便讓我們來談談指標。我運行了一些測試代碼,以獲得一些性能指標使用Visual Studio 2010和
我得到這些指標,通過計算10個測試運行的任一方法的平均時間,每次1000萬次迭代,然後在調試然後釋放模式下(非優化然後優化):
(調試) 鑄造方法:〜32毫秒 分配方法:〜26毫秒
(釋放) 鑄造方法:〜20毫秒 分配方法:〜22毫秒
什麼是另外一個有趣的地方是將這些指標與託管C++的類似代碼進行比較,僅使用gcnew,結果大不相同。
再次設置相同。除了比較鑄造方法:「IntPtr^ptr =(IntPtr)i;」 vs分配方法:「IntPtr^ptr =(IntPtr)i;」。
(調試) 鑄造方法:〜91ms 分配方法:〜127ms
(釋放) 鑄造方法:〜22ms內 分配方法:〜124ms
現在,如果你抓你的頭說:那麼爲什麼C#比託管C++快得多,答案不是。使用IntPtr的最有效方式是作爲值類型而不是對值類型的引用。例如像這樣「IntPtr ptr =(IntPtr)i;」。這會給你〜24ms(更多調試)或(〜22發佈模式)。看看它如何被編譯器優化以獲得22ms而不是90ms。
在C#中的結論,除非你真的看到嚴格的緊密代碼,這並不重要。我認爲在Release中我的代碼實際上是優化了演員,因爲評論演員給出了相同的〜22ms。但是大多數情況下,編譯器在C#中都支持這個,至少VS 2010是這樣的。但是,如果您正在查看具有最小性能限制的代碼,請在Managed C++/CLI中注意。編譯器不會自動優化gcnew分配到cast方法,它的速度幾乎快6倍......我在C++/CLI中遇到了這個特殊問題,這導致我在處理某些實時音頻時在此線程上發佈處理。我的代碼(C#):(我管理的C++代碼非常相似,除了必須自己編寫Average()並使用控制檯輸出而不是消息框)。
static void Main()
{
List<int> castTimings = new List<int>();
List<int> allocTimings = new List<int>();
for (int i = 0; i < TEST_RUNS; ++i)
{
castTimings.Add(RunCastMethod().Milliseconds);
allocTimings.Add(RunAllocationMethod().Milliseconds);
}
MessageBox.Show(string.Format("Casting Method took: {0}ms", castTimings.Average()));
MessageBox.Show(string.Format("Allocation Method took: {0}ms", allocTimings.Average()));
}
private static TimeSpan RunAllocationMethod() {
DateTime start = DateTime.Now;
for (int i = 0; i < TEST_ITERATIONS; ++i)
{
IntPtr ptr = new IntPtr(i);
}
return (DateTime.Now - start);
}
private static TimeSpan RunCastMethod()
{
DateTime start = DateTime.Now;
for (int i = 0; i < TEST_ITERATIONS; ++i)
{
IntPtr ptr = (IntPtr) i;
}
return (DateTime.Now - start);
}
謝謝你的努力mede – 2010-12-14 05:51:53
IntPtr是一個值類型的事實並不意味着new不會分配內存。事實上,使用new應該是首選的,以確保結構被正確初始化。 – 2009-08-06 05:40:37
我想帕維爾的意思是,它不使用任何其他方式都不會使用的內存。顯然,複製值類型意味着將使用更多的內存:) – Thorarin 2009-08-06 06:16:00
使用(或不使用)'new'將確保結構已正確初始化絕對沒有任何好處。對於初學者來說,首先你不能有一個「不正確的初始化結構」,因爲編譯器會強制執行本地初始化,並且默認初始化其他所有內容。 – 2009-08-06 07:31:14