c# – 为什么UInt16数组似乎比int数组更快?

似乎C#在添加两个UInt16 []数组时比在添加两个int []数组时更快.这对我来说没有意义,因为我会假设数组是字对齐的,因此int []需要较少的CPU工作,不是吗?

我运行了下面的测试代码,得到了以下结果:

Int    for 1000 took 9896625613 tick (4227 msec)
UInt16 for 1000 took 6297688551 tick (2689 msec)

测试代码执行以下操作:

>创建两个名为a和b的数组,一次.
>用随机数据填充一次.
>启动秒表.
>逐项添加a和b.这样做了1000次.
>停止秒表.
>报告花了多长时间.

这是针对int [] a,b和UInt16 a,b完成的.每次运行代码时,UInt16阵列的测试时间比int数组少30%-50%.你能解释一下吗?

这是代码,如果你想尝试自己:

public static UInt16[] GenerateRandomDataUInt16(int length)
{
    UInt16[] noise = new UInt16[length];
    Random random = new Random((int)DateTime.Now.Ticks);
    for (int i = 0; i < length; ++i)
    {
        noise[i] = (UInt16)random.Next();
    }

    return noise;
}

public static int[] GenerateRandomDataInt(int length)
{
    int[] noise = new int[length];
    Random random = new Random((int)DateTime.Now.Ticks);
    for (int i = 0; i < length; ++i)
    {
        noise[i] = (int)random.Next();
    }

    return noise;
}

public static int[] AddInt(int[] a,int[] b)
{
    int len = a.Length;
    int[] result = new int[len];
    for (int i = 0; i < len; ++i)
    {
        result[i] = (int)(a[i] + b[i]);
    }
    return result;
}

public static UInt16[] AddUInt16(UInt16[] a,UInt16[] b)
{
    int len = a.Length;
    UInt16[] result = new UInt16[len];
    for (int i = 0; i < len; ++i)
    {
        result[i] = (ushort)(a[i] + b[i]);
    }
    return result;
}


public static void Main()
{
    int count = 1000;
    int len = 128 * 6000;

    int[] aInt = GenerateRandomDataInt(len);
    int[] bInt = GenerateRandomDataInt(len);

    Stopwatch s = new Stopwatch();
    s.Start();
    for (int i=0; i<count; ++i) 
    {
        int[] resultInt = AddInt(aInt,bInt);
    }
    s.Stop();
    Console.WriteLine("Int    for " + count 
                + " took " + s.ElapsedTicks + " tick (" 
                + s.ElapsedMilliseconds + " msec)");

    UInt16[] aUInt16 = GenerateRandomDataUInt16(len);
    UInt16[] bUInt16 = GenerateRandomDataUInt16(len);

    s = new Stopwatch();
    s.Start();
    for (int i=0; i<count; ++i) 
    {
        UInt16[] resultUInt16 = AddUInt16(aUInt16,bUInt16);
    }
    s.Stop();
    Console.WriteLine("UInt16 for " + count 
                + " took " + s.ElapsedTicks + " tick (" 
                + s.ElapsedMilliseconds + " msec)");


}

解决方法

会发生什么是你看到一个漏洞的抽象. UInt16占用int的一半内存(16对32位).

这意味着int16数组占用的内存区占用int32所占区域的一半.因此,更多的区域可以适应处理器缓存,因此可以非常快速地访问.

您可以在具有更多缓存的处理器上尝试该代码,并且差异可能更小.

也尝试使用更大的阵列.

相关文章

项目中经常遇到CSV文件的读写需求,其中的难点主要是CSV文件...
简介 本文的初衷是希望帮助那些有其它平台视觉算法开发经验的...
这篇文章主要简单记录一下C#项目的dll文件管理方法,以便后期...
在C#中的使用JSON序列化及反序列化时,推荐使用Json.NET——...
事件总线是对发布-订阅模式的一种实现,是一种集中式事件处理...
通用翻译API的HTTPS 地址为https://fanyi-api.baidu.com/api...