C#中的算法实现似乎是灾难性的

时间:2015-07-22 04:41:31

标签: c# c++ algorithm performance optimization

我试图实施本研究论文中指定的算法: [这里 - 请忽略数学,因为它与问题无关] [2]。该算法在形式概念分析中非常基础。输入是一个矩阵NXM,存储为X.存储在.txt文件中。根据本文中嵌入的伪代码,输入必须也表示为矩阵

1 个答案:

答案 0 :(得分:2)

如果没有能够看到您正在与之进行比较的C ++实现的源代码,则无法确定它比C#代码快得多的原因,但由于您的每个值都是0或1然后你可以做的一个优化(以使代码更复杂为代价)是将值存储在某种位掩码数据结构中,或者只是作为int数组中的压缩位值并使用位操作操作来操作他们。 C ++实现可能正在这样做,但为了便于解释,这并未在已发布的伪代码中显示。

例如,由于CT_WIDTH为126,因此可以以4 x 32位整数(128位)存储单行,而不是126个整数。

然后这样的操作:

match = true;
for (int j = 0; j < CT_WIDTH; j++)
{
    if (B[j] == 1 && FCAContext[rows[y][i] * CT_WIDTH + j] == 0)
    {
        match = false;
        break;
    }
}

可以像这样重写,有效地一次处理32个值:

// CT_WIDTH_SHIFTED = (CT_WIDTH + 31) / 32
match = true;
int index = rows[y][i] * CT_WIDTH_SHIFTED;
for (int j = 0; j < CT_WIDTH_SHIFTED; j++)
{
    if (B[j] & FCAContext[index + j] != B[j])
    {
        match = false;
        break;
    }
}

同样,这:

for (int j = 0; j < CT_WIDTH; j++)
    if (FCAContext[rows[y][i] * CT_WIDTH + j] == 0)
         D[j] = 0;

可以改写为

for (int j = 0; j < CT_WIDTH_SHIFTED; j++)
    D[j] &= FCAContext[index + j];

FCAContext,D和B中的值需要存储为打包位。

例如,要在数组中设置一个位,而不是使用这样的代码来设置int数组的第j个元素:

B[j] = 1;

你首先通过将j除以32除以5(j> 5)来计算索引,并计算元素内的位,如1&lt;&lt;&lt; (j&amp; 31),其中一个向右移动j除以32的余数,然后使用按位OR运算设置它:

B[j >> 5] |= 1 << (j & 31)

Here's关于位屏蔽的在线教程。谷歌&#34;位操作&#34;,&#34;位移&#34;,&#34;位屏蔽&#34; &#34;有点黑客&#34;和&#34;位操作&#34; /&#34;按位运算&#34;欲获得更多信息。位操作可能会非常繁琐,但却使您的代码难以阅读。

还要考虑使用.NET BitArray类。