创建浮点数时,它的默认值为零。但是,我希望它默认为 NaN,因为该值应该是未知的,或者换句话说,它应该指示尚未为其分配任何值。稍后我将在可能的情况下分配值,在不可能的情况下,该属性应保留为 NaN,因为找不到它的值。因此,NaN 是适当的起始状态。所以,这就是我所做的:
class SmallObject
{
public float A { get; set; } = float.NaN; // slow, but the value is NaN, which is correct
public float B { get; set; } = float.NaN; // slow, but the value is NaN, which is correct
public float C { get; set; } = float.NaN; // slow, but the value is NaN, which is correct
public float D { get; set; } = float.NaN; // slow, but the value is NaN, which is correct
public float E { get; set; } = float.NaN; // slow, but the value is NaN, which is correct
}
所有属性都使用 float 初始化。NaN,但问题是,这非常慢,因为属性是用值初始化的,我正在创建数百万个 SmallObject。下面的速度要快得多,但属性值为零:
class SmallObject
{
public float A { get; set; } // fast, but the value is zero, which is wrong
public float B { get; set; } // fast, but the value is zero, which is wrong
public float C { get; set; } // fast, but the value is zero, which is wrong
public float D { get; set; } // fast, but the value is zero, which is wrong
public float E { get; set; } // fast, but the value is zero, which is wrong
}
我想要的是这样的东西:
class SmallObject
{
public myFloat A { get; set; } // fast, and the value is NaN, which is correct
public myFloat B { get; set; } // fast, and the value is NaN, which is correct
public myFloat C { get; set; } // fast, and the value is NaN, which is correct
public myFloat D { get; set; } // fast, and the value is NaN, which is correct
public myFloat E { get; set; } // fast, and the value is NaN, which is correct
}
在这里,myFloat 是一个默认为 NaN 的自定义浮点数,没有任何开销,因此它的运行速度与默认为零的普通浮点数一样快。这可能吗?谢谢。
更新
由于评论的反馈,我决定提供度量来支持我的说法,即用值初始化浮点数比不理会它慢。
创建 1000 万个具有 float 5 个属性的小对象:
释放 32- 位:32 ms
- 释放 64 位:4 ms
创建 1000 万个小对象,其中 5 个属性的浮点数初始化为浮点数。南:
- 释放 32 位:44 ms
- 释放 64 位:53 ms
创建 1000 万个具有 5 个浮点属性的小对象?
- 释放 32 位:43 ms
- 释放 64 位:4 ms
所有结果均为中位数。如您所见,将浮点数初始化为 NaN 比在 64 位发布时将其初始化慢13.25 倍。总之,对于 64 位版本,浮动?是创建对象时的最佳选择。但是,我注意到下游,漂浮?由于必须经常将其转换为常规浮点数以进行计算,可能会导致问题(例如。Math.Abs 和 Math.Log 以及 BitConverter(。
您可以创建可为空的浮点数。可在 C# 2.0 中引入可为空的类型。
float? myNullableFloat;
这应该可以解决它:
private float foo = Single.NaN;
public float Foo { get => foo; set => foo = value; }