将浮点数的默认值设置为 NaN?



创建浮点数时,它的默认值为零。但是,我希望它默认为 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; }

最新更新