Question : 判斷一個浮點數輸入值, 是不是剛好是整數, 範例輸出入如下 (input → output)。
答案揭曉, Math 類操作最快, 也就是上述 IsIntegerFloor() 版本; 扣除掉本來就會 BG 的 IsIntegerByParse() 版本, 雖然比剩餘兩個版本快, 但差異幾乎可以忽略。翻 Math.Floor 原始碼, 原來又是個的 native 函式。
至於為何要用這種寫法呢, 網路上的 討論 頗多, 但參考 MSDN 的描述, 一言以蔽之, 就是「它會呼叫 CLR 內的方法」。
- 11.112 → false
- 11.000 → true
public static bool IsIntegerByMath(float f)
{
return Math.Ceiling(f) == Math.Floor(f);
}
public static bool IsIntegerByParse(float f)
{
int i;
return int.TryParse(f.ToString(), out i);
}
如此一來, 程式會動了, 考試應該也有過。但若要追求簡潔或效能的極致, 還有以下的做法。public static bool IsIntegerByMode(float f)
{
return f % 1 == 0;
}
public static bool IsIntegerFloor(float f)
{
return f == Math.Floor(f);
}
網路上的這兩個版本, 直接理解 C# 語言對於浮點數與整數的相互操作, 寫出更高效的寫法。而上面的執行效率各是如何 ? 未測先估 TryParse 是最慢的, 但最快的版本究竟快在哪裡 ? 跑個 1,000 萬次來試試。答案揭曉, Math 類操作最快, 也就是上述 IsIntegerFloor() 版本; 扣除掉本來就會 BG 的 IsIntegerByParse() 版本, 雖然比剩餘兩個版本快, 但差異幾乎可以忽略。翻 Math.Floor 原始碼, 原來又是個的 native 函式。
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern double Floor(double d);
至於為何要用這種寫法呢, 網路上的 討論 頗多, 但參考 MSDN 的描述, 一言以蔽之, 就是「它會呼叫 CLR 內的方法」。
成員名稱 | 描述 |
AggressiveInlining | 此方法應該盡可能內嵌。 |
ForwardRef | 方法已宣告,但是其實作在其他地方提供。 |
InternalCall | 呼叫是內部的,亦即,它會呼叫在 Common Language Runtime 內實作的方法。The call is internal, that is, it calls a method that is implemented within the common language runtime. |
NoInlining | 方法無法內嵌。 內嵌是一項最佳化作業,透過該作業,方法呼叫可使用方法主體取代。 |
NoOptimization | 對可能的程式碼產生問題進行偵錯時,方法不是由 Just-In-Time (JIT) 編譯器或原生程式碼產生最佳化 (請參閱 Ngen.exe (https://msdn.microsoft.com/zh-tw/library/6t9t5wcf(v=vs.110).aspx))。 |
PreserveSig | 方法簽章會完全依宣告方式匯出。 |
Synchronized | 方法一次只能由一個執行緒來執行。 靜態方法鎖定型別,而執行個體方法鎖定執行個體。 在任何執行個體函式中只能執行一個執行緒,且只有一個執行緒可在任何類別的靜態函式中執行。 |
Unmanaged | 方法是以 Unmanaged 程式碼實作。 |
參考資料
- https://msdn.microsoft.com/zh-tw/library/system.runtime.compilerservices.methodimploptions(v=vs.110).aspx
- https://github.com/Microsoft/referencesource/blob/master/mscorlib/system/math.cs
- https://stackoverflow.com/questions/142252/test-if-a-floating-point-number-is-an-integer
- https://stackoverflow.com/questions/11161120/whats-the-point-of-methodimploptions-internalcall
Comments
Post a Comment