在该代码中我有一个我不明白的问题:
ilProbekUcz= valuesUcz.Count; //valuesUcz is the list of <float[]>
for (int i = 0; i < ilWezlowDanych; i++) nodesValueArrayUcz[i] = new BitArray(ilProbekUcz);
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < ilProbekUcz; i++)
{
int index = 0;
linia = (float[])valuesUcz[i];//removing this line not solve problem
for (int a = 0; a < ileRazem; a++)
for (int b = 0; b < ileRazem; b++)
if (a != b)
{
bool value = linia[a] >= linia[b];
nodesValueArrayUcz[index][i] = value;
nodesValueArrayUcz[ilWezlowDanychP2 + index][i] = !value;
index++;
}
}
sw.Stop();
当我将valuesUcz
的大小增加2倍时,执行时间将增加4倍
当我将valuesUcz
的大小增加4倍时,执行时间将增加8倍
等等...
({ileRazem
,ilWezlowDanych
相同)
我了解:增加ilProbekUcz
会增加BitArrays
的大小,但是我对其进行了多次测试,这没问题-时间应该线性增长-在代码中:
ilProbekUcz= valuesUcz.Count; //valuesTest is the list of float[]
for (int i = 0; i < ilWezlowDanych; i++) nodesValueArrayUcz[i] = new BitArray(ilProbekUcz);
BitArray test1 = nodesValueArrayUcz[10];
BitArray test2 = nodesValueArrayUcz[20];
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < ilProbekUcz; i++)
{
int index = 0;
linia = (float[])valuesUcz[i];//removing this line not solve problem
for (int a = 0; a < ileRazem; a++)
for (int b = 0; b < ileRazem; b++)
if (a != b)
{
bool value = linia[a] >= linia[b];
test1[i] = value;
test2[i] = !value;
index++;
}
}
时间线性增长,所以问题是从数组中提取BitArray
...
有什么方法可以更快地做到这一点? (我想让时间线性增长)
答案 0 :(得分:1)
您必须了解,测量时间有很多因素使他们不准确。如示例中所示,具有大数组时最大的因素是cashe misses
。考虑到 cashe 时,编写同一件东西的速度通常可以快2-5倍甚至更多倍。这两个词非常粗略地说明了工作原理。缓存是cpu中的内存。它比ram快waaaaaaaaaaaaaaaay,因此,当您要从内存中获取变量时,需要确保此变量存储在缓存中而不是ram中。如果存储在缓存中,我们说我们有一个hit
,否则是miss
。有时,程序不是那么大,以至于它会将变量存储在硬盘中。在这种情况下,您在获取这些内容时会遇到huuuuuuuuuuuge的延迟!缓存示例:
假设我们在内存(ram)中有10个元素的数组
当您获得第一个元素testArray[0]
时,因为 testArray [0] 不在缓存中,CPU会将此值以及带数字(请说3,该数字取决于数组的相邻元素的cpu),例如它存储到缓存testArray[0], testArray[1], testArray[2], testArray[3]
现在,当我们得到testArray[1]
时,它在缓存中,因此我们有了hit
。 testArray[2]
和testArray[3]
相同。 testArray[4]
不在缓存中,因此它与另外3个testArray[4]
testArray[5], testArray[6], testArray[7]
以此类推...
缓存misses
的成本很高。这意味着您可能希望两倍大小的数组可以访问两倍的时间。但是这是错误的。更大的数组更多misses
并且时间可能会比您预期的增加2或3或4倍或更多倍。这是正常的。在您的示例中就是这样。从1亿个元素(第一个数组)开始,您将达到0亿个(第二个)。 misses
不是两倍,而是您所看到的更多。一个非常酷的技巧与访问数组的方式有关。在您的示例中,ba1[j][i] = (j % 2) == 0;
比ba1[i][j] = (j % 2) == 0;
差很多。 ba2[j][i] = (j % 2) == 0;
和ba1[i][j] = (j % 2) == 0;
相同。你可以测试一下。只需反转i and j
。这与2D数组在内存中的存储方式有关,因此在第二种情况下,您比第一种情况拥有更多的hits
。