![](/img/trans.png)
[英]C# - What's the fastest way to convert a number to the smallest BitArray
[英]What's the fastest way to get the partial value of a number in C#?
float f = 5.13;
double d = 5.13;
float fp = f - (float)Math.floor(f);
double dp = d - Math.floor(d);
有沒有比每次調用外部函數更快的方法?
“外部功能”?
System.Math內置於mscorlib中!
這實際上是最快的方法。
您可以將f轉換為int,這將修剪小數部分。 這假設您的雙打屬於整數范圍。
當然,抖動可能足夠聰明,可以將Math.floor優化為一些內聯的asm,它可以比執行轉換更快,然后轉換為浮動。
您是否真的已經測量並驗證了Math.floor的性能是否會影響您的程序? 如果還沒有,在你知道這是一個問題之前,你不應該為這個級別的微優化而煩惱,然后根據原始代碼測量這個替代方案的性能。
編輯:這看起來更快。 使用Math.Floor()時,以下代碼需要717ms,在發布模式下,我的機器上的int cast代碼需要172 ms。 但同樣,我懷疑性能提升真的很重要 - 為了讓這個可以測量我必須進行100米迭代。 此外,我發現Math.Floor()更具可讀性和明顯意圖,未來的CLR可以為Math.Floor發出更優化的代碼,並輕松擊敗這種方法。
private static double Floor1Test()
{
// Keep track of results in total so ops aren't optimized away.
double total = 0;
for (int i = 0; i < 100000000; i++)
{
float f = 5.13f;
double d = 5.13;
float fp = f - (float)Math.Floor(f);
double dp = d - (float)Math.Floor(d);
total = fp + dp;
}
return total;
}
private static double Floor2Test()
{
// Keep track of total so ops aren't optimized away.
double total = 0;
for (int i = 0; i < 100000000; i++)
{
float f = 5.13f;
double d = 5.13;
float fp = f - (int)(f);
double dp = d - (int)(d);
total = fp + dp;
}
return total;
}
static void Main(string[] args)
{
System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
// Unused run first, guarantee code is JIT'd.
timer.Start();
Floor1Test();
Floor2Test();
timer.Stop();
timer.Reset();
timer.Start();
Floor1Test();
timer.Stop();
long floor1time = timer.ElapsedMilliseconds;
timer.Reset();
timer.Start();
Floor2Test();
timer.Stop();
long floor2time = timer.ElapsedMilliseconds;
Console.WriteLine("Floor 1 - {0} ms", floor1time);
Console.WriteLine("Floor 2 - {0} ms", floor2time);
}
}
Donald E. Knuth說:
“我們應該忘記小的效率,比如大約97%的時間:過早的優化是所有邪惡的根源。”
因此,除非您對應用程序進行基准測試並發現此操作是瓶頸的正面證據,否則不要費心優化這些代碼。
嗯,我懷疑你會獲得任何真實的世界性能增益,但根據Reflector Math.Floor是這樣的:
public static decimal Floor(decimal d)
{
return decimal.Floor(d);
}
所以可以說
double dp = d - decimal.Floor(d);
可能會更快。 (編譯器優化使我知道的整點意義不大......)
對於那些可能有興趣將其帶入其邏輯結論十進制的人。地板是:
public static decimal Floor(decimal d)
{
decimal result = 0M;
FCallFloor(ref result, d);
return result;
}
FCallFloor是對非托管代碼的調用,因此您幾乎處於“優化”的極限。
在Decimal
的情況下,我建議忽略大家不要改變它並嘗試使用Decimal.Truncate
。 無論是否更快,它都是專門針對您要做的事情的功能,因此更清晰一點。
哦,順便說一句,它更快:
System.Diagnostics.Stopwatch foo = new System.Diagnostics.Stopwatch();
Decimal x = 1.5M;
Decimal y = 1;
int tests = 1000000;
foo.Start();
for (int z = 0; z < tests; ++z)
{
y = x - Decimal.Truncate(x);
}
foo.Stop();
Console.WriteLine(foo.ElapsedMilliseconds);
foo.Reset();
foo.Start();
for (int z = 0; z < tests; ++z)
{
y = x - Math.Floor(x);
}
foo.Stop();
Console.WriteLine(foo.ElapsedMilliseconds);
Console.ReadKey();
//Output: 123
//Output: 164
編輯:修正了我的解釋和代碼。
它是靜態的,所以這應該非常快,沒有任何目標可以站起來。 您可以隨時進行數學水平計算,但除非您有一些認真使用該功能。 可能floor()方法已經這樣做了,但如果你需要非常快的東西,你可以內聯它並刪除支票等,但在C#中這不是你最大的性能問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.