0

私は BitConvert の速度を向上させようとしています。むしろ、別の方法です。

だからここに私が思っていたより速いはずのコードがあります:

    bsize = ms.length
    int index = 0;
    byte[] target = new byte[intsize];
    target[index++] = (byte)bsize;
    target[index++] = (byte)(bsize >> 8);
    target[index++] = (byte)(bsize >> 16);
    target[index] = (byte)(bsize >> 24);

そして、BitConvert コード:

BitConverter.GetBytes(bsize)

まあ、それは速くはありませんでした。私のテストではかなり遅く、2 倍以上遅くなりました。

では、なぜ遅いのでしょうか。また、速度を上げる方法はありますか?

編集:

BitConvert = 5068 Ticks

OtherMethod above: 12847 Ticks

編集 2: 私のベンチマーク コード:

private unsafe void ExecuteBenchmark(int samplingSize = 100000)
    {
        // run the Garbage collector
        GC.Collect();
        GC.WaitForPendingFinalizers();

        // log start
        Console.WriteLine("Benchmark started");

        // start timer
        var t = Stopwatch.StartNew();

                for (int i = 0; i < samplingSize; i++)
                {

                }
        }
        // stop timer
        t.Stop();
        // log ending
        Console.WriteLine("Execute1 time = " + t.ElapsedTicks + " ticks");
    }
4

2 に答える 2

3

ポインターを操作するコードをBitConverter使用するため、実装は遅くなります。unsafe

public unsafe static byte[] GetBytes(int value)
{
    byte[] array = new byte[4];
    fixed (byte* ptr = array)
    {
        *(int*)ptr = value;
    }
    return array;
}

そして戻るint

public unsafe static int ToInt32(byte[] value, int startIndex)
{
    if (value == null)
    {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
    }
    if ((ulong)startIndex >= (ulong)((long)value.Length))
    {
        ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
    }
    if (startIndex > value.Length - 4)
    {
        ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
    }
    int result;
    if (startIndex % 4 == 0)
    {
        result = *(int*)(&value[startIndex]);
    }
    else
    {
        if (BitConverter.IsLittleEndian)
        {
            result = ((int)(*(&value[startIndex])) | (int)(&value[startIndex])[(IntPtr)1 / 1] << 8 | (int)(&value[startIndex])[(IntPtr)2 / 1] << 16 | (int)(&value[startIndex])[(IntPtr)3 / 1] << 24);
        }
        else
        {
            result = ((int)(*(&value[startIndex])) << 24 | (int)(&value[startIndex])[(IntPtr)1 / 1] << 16 | (int)(&value[startIndex])[(IntPtr)2 / 1] << 8 | (int)(&value[startIndex])[(IntPtr)3 / 1]);
        }
    }
    return result;
}
于 2013-08-17T21:14:10.113 に答える
2

まず、このような少量のコードの速度を測定すると、エラーが発生しやすくなります。ベンチマークを投稿すると、より多くの答えが得られる場合があります。

しかし、それをサポートするプラットフォーム (x86 など) では、BitConverter はおそらく、target3 つのシフト、4 つの境界チェック、および 4 つの書き込みではなく、単一の境界チェックと非整列書き込みを行うと思います。最終的には完全にインライン化される可能性があり、すべての呼び出しオーバーヘッドが軽減されます。

于 2013-08-17T21:06:19.193 に答える