有没有什么方法可以在C#中快速比较两个花车的迹象?我怀疑一次又一次地将浮点数与0进行比较的表现。但是,似乎在C#中禁止浮点操作,因此我们不能使用像(a ^ b)& 0x80000000或((a>>> 31)==(b>> 31))这样的方法来确定(在这里忽略0的情况)。
关于从float到int(没有指针)的转换问题是舍入的,因为每个小于1的数字都将舍入为0。
从float转换为int(带指针)的问题只有两个可能的返回值,无法识别0。
现在是时候测试预判0和使用指针的组合的表现。
(关于我在这里犯过的错误的删除)
答案 0 :(得分:0)
如果您使用unsafe
,您可以使用指针将这些位转换为int
,然后您可以执行按位操作
*(int*)(&val1) >> 31 == *(int*)&val2 >> 31;
如果您担心性能,可以使用MethodImplOptions.AggressiveInlining
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe bool IsSameSign(float val1, float val2)
{
return *(int*)(&val1) >> 31 == *(int*)&val2 >> 31;
}
为了您的娱乐,我针对您的原始版本做了一些基准测试。我通过100,000次比较运行每次测试50次,分别为1,000,000次
Test Framework : .NET Framework 4.7.1
Scale : 100000
Name | Time | Delta | Deviation | Cycles
-----------------------------------------------------------------
MySameSign | 1.045 ms | 0.052 ms | 0.20 | 3,498,252
BaseSameSign | 15.391 ms | 0.548 ms | 0.81 | 52,181,763
Scale : 1000000
Name | Time | Delta | Deviation | Cycles
-------------------------------------------------------------------
MySameSign | 10.000 ms | 0.232 ms | 0.31 | 33,995,263
BaseSameSign | 146.250 ms | 1.311 ms | 1.13 | 498,064,434
示例数据
static float NextFloat()
{
double mantissa = (_rand.NextDouble() * 2.0) - 1.0;
double exponent = Math.Pow(2.0, _rand.Next(-126, 128));
return (float)(mantissa * exponent);
}
public static List<Tuple<float,float>> GenerateSignInput(int scale)
{
return Enumerable.Range(1, scale)
.Select(x => new Tuple<float, float>(NextFloat(), NextFloat()))
.ToList();
}