我想将Date
的{{1}}部分序列化为4个字节(可能是Int32)。最快的方法是什么?
背景:为了序列化一个完整的DateTime
,到目前为止我一直在使用DateTime
方法。它返回ToBinary
,我将其存储在其他位置。现在,我需要仅使用一半空间来存储Int64
Date
部分。所以,我想知道如何以最快的方式实现这一点,因为性能至关重要。
我想到的选项是:
DateTime
编码为YYYYMMDD,这种编码具有人类可读的良好副作用。int
并仅保留"上半部分或下半部分"返回的ToBinary
。不知道这是否可能。long
的方式。也许可以通过其他方式访问日期部分。你会怎么做?
答案 0 :(得分:7)
DateTime
被存储为自0001年1月1日00:00:00以来的刻度数。因此,如果您使用DateTime的Ticks
并将其除以TimeSpan.TicksPerDay
,那么结束自0001年1月1日以来的天数。
反向操作(乘以TimeSpan.TicksPerDay
)反序列化时。
由于DateTime
涵盖范围内“仅”3,652,058天,因此很容易适合Int32
序列化:
System.DateTime toSerialize;
long longDays = toSerialize.Ticks / System.TimeSpan.TicksPerDay;
// Safe since (DateTime.MaxValue - DateTime.MinValue).Days << Int32.MaxValue
int days = (int)longDays;
// Serializes `days` however you would serialize any other int
反序列化:
int days;
long ticks = days * System.TimeSpan.TicksPerDay;
System.DateTime deserialized = new DateTime(ticks);
答案 1 :(得分:2)
.net Year
(0001-9999)支持的任何DateTime
都适合short
,即2个字节。 <{1}}和Day
将分别为Month
。
因此,您只需创建一个包含所有三个字段的自定义结构。
byte
你可以序列化这个4字节的结构(假设没有填充)。您可以只存储结构的字节表示,因为此结构是blittable。
如果您可以使用不安全的代码,那么转换可以非常快速地进行。否则use one of the .Net'ish way
public struct Date
{
public readonly short Year;//2 byte
public readonly byte Month;//1 byte
public readonly byte Day; //1 byte
...
}
或者你可以使用专为处理这类事情而设计的private unsafe int DateToInt(Date date)
{
int* d = (int*)&date;
return *d;
}
private unsafe Date IntToDate(int date)
{
Date* d = (Date*)(&date);
return *d;
}
。
BitVector32