[英]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.