提高将字节转换为 UInt32 的性能

问题描述

我正在编写处理 2GB 数据的源代码,这些数据代表 60 秒的网络流量。总处理时间约为 40 秒。我正在尝试尽可能优化我的代码以获得最佳性能,以尝试将总处理时间控制在 30 秒以内。

Thread Time

我目前在 dotTrace 中的分析表明,在我的代码进行的 330 万次调用中,有 7.62% 的时间花在了 Timestamp 结构的构造函数中。

Constructor

具体来说,有两个陈述我正在努力改进:

TimestampHigh = BitConverter.ToUInt32(timestampBytes,0);
TimestampLow = BitConverter.ToUInt32(timestampBytes,4);

这是完整的结构:

public readonly struct Timestamp
{
    public uint TimestampHigh { get; }
    public uint TimestampLow { get; }
    public uint Seconds { get; }
    public uint Microseconds { get; }
    public DateTime LocalTime => new DateTime(EpochTicks + _ticks,DateTimeKind.Utc).ToLocalTime();

    private const ulong MicrosecondsPerSecond = 1000000UL;
    private const ulong HighFactor = 4294967296UL;
    private readonly ulong _timestamp;

    private const long EpochTicks = 621355968000000000L;
    private const long TicksPerMicrosecond = 10L;
    private readonly long _ticks;

    public Timestamp(byte[] timestampBytes,bool reverseByteOrder)
    {
        if (timestampBytes == null)
            throw new ArgumentNullException($"{nameof(timestampBytes)} cannot be null.");
        if (timestampBytes.Length != 8)
            throw new ArgumentException($"{nameof(timestampBytes)} must have a length of 8.");

        TimestampHigh = BitConverter.ToUInt32(timestampBytes,0).ReverseByteOrder(reverseByteOrder);
        TimestampLow = BitConverter.ToUInt32(timestampBytes,4).ReverseByteOrder(reverseByteOrder);
        _timestamp = ((ulong)TimestampHigh * HighFactor) + (ulong)TimestampLow;
        _ticks = (long)_timestamp * TicksPerMicrosecond;
        Seconds = (uint)(_timestamp / MicrosecondsPerSecond);
        Microseconds = (uint)(_timestamp % MicrosecondsPerSecond);
    }

    public Timestamp(uint seconds,uint microseconds)
    {
        Seconds = seconds;
        Microseconds = microseconds;
        _timestamp = seconds * MicrosecondsPerSecond + microseconds;
        _ticks = (long)_timestamp * TicksPerMicrosecond;
        TimestampHigh = (uint)(_timestamp / HighFactor);
        TimestampLow = (uint)(_timestamp % HighFactor);
    }

    public byte[] ConvertToBytes(bool reverseByteOrder)
    {
        List<byte> bytes = new List<byte>();
        bytes.AddRange(BitConverter.GetBytes(TimestampHigh.ReverseByteOrder(reverseByteOrder)));
        bytes.AddRange(BitConverter.GetBytes(TimestampLow.ReverseByteOrder(reverseByteOrder)));

        return bytes.ToArray();
    }

    public bool Equals(Timestamp other)
    {
        return TimestampLow == other.TimestampLow && TimestampHigh == other.TimestampHigh;
    }

    public static bool operator ==(Timestamp left,Timestamp right)
    {
        return left.Equals(right);
    }

    public static bool operator !=(Timestamp left,Timestamp right)
    {
        return !left.Equals(right);
    }

    public override bool Equals(object obj)
    {
        return obj is Timestamp other && Equals(other);
    }

    public override int GetHashCode()
    {
        return _timestamp.GetHashCode();
    }
}

ReverseByteOrder 方法似乎不会造成太大的性能损失,因为根据 dotTrace,它只占不到 0.5% 的时间,但此处仅供参考:

public static UInt32 ReverseByteOrder(this UInt32 value,bool reverseByteOrder)
{
    if (!reverseByteOrder)
    {
        return value;
    }
    else
    {
        byte[] bytes = BitConverter.GetBytes(value);
        Array.Reverse(bytes);
        return BitConverter.ToUInt32(bytes,0);
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)