Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#中的算法实现似乎是灾难性的_C#_C++_Algorithm_Performance_Optimization - Fatal编程技术网

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

C#中的算法实现似乎是灾难性的,c#,c++,algorithm,performance,optimization,C#,C++,Algorithm,Performance,Optimization,我试图实现这篇研究论文中指定的算法: [此处-请忽略数学,因为它与问题无关][2]。该算法是形式概念分析的基础。输入是一个矩阵NXM,存储为X和在.txt文件中。根据本文中嵌入的伪代码,输入必须表示为矩阵,也不代表能看到C++的实现的源代码,而不能比较清楚地说明为什么它比C代码快得多。但是,由于每个值都是0或1,因此可以进行的一个优化(代价是使代码更加复杂)是将值存储在某种位掩码数据结构中,或者将其作为压缩位值存储在int数组中,并使用位操纵操作来操纵它们。C++实现可能是这样做的,但是在发布的

我试图实现这篇研究论文中指定的算法:
[此处-请忽略数学,因为它与问题无关][2]。该算法是形式概念分析的基础。输入是一个矩阵
NXM
,存储为
X
在.txt文件中。根据本文中嵌入的伪代码,输入必须表示为矩阵,也不代表能看到C++的实现的源代码,而不能比较清楚地说明为什么它比C代码快得多。但是,由于每个值都是0或1,因此可以进行的一个优化(代价是使代码更加复杂)是将值存储在某种位掩码数据结构中,或者将其作为压缩位值存储在int数组中,并使用位操纵操作来操纵它们。C++实现可能是这样做的,但是在发布的伪代码中没有显示,以便于解释。 例如,由于CT_宽度为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;
    }
}

首先,您将通过左移5(j>>5)将j除以32来计算索引,并计算元素内部的位,如1>5]|=1,假设您的实际测试测量忽略JIT时间,并且您在不使用调试器的情况下运行发布构建。。。下一步是使用用户档案器,查看花费的时间最多的地方。。。一般来说,这样的问题会引起别人的兴趣,你不需要任何努力就可以得到优化的版本(这也是一个机会游戏)。如果没有这一点,你就不可能得到任何有帮助的具体答案。至于“C#是否和C++一样好”,当然是这样,但每种语言都有其优缺点。尽管如此,即使是一个天真但却能胜任的C++算法版本,应该在非托管代码的性能的10-20%以内,并且努力(并且可能使用<代码>不安全< /code >代码)应该能够实现奇偶校验。对于正确的端口,35x的差异是前所未闻的。在不将C++源作为参考的情况下,很难回答这个问题。你的代码产生了正确的结果吗?事实上,它确实产生了,它刚刚做的非常奇怪,如果你能发布一个完整的例子,我们可以为自己编译,并有预期的输出,然后可以重构你的代码,使之更正常。在
generate\u from
中,新的
int[]D
s在
中被重复分配(int j
compute\u closure
。D始终是
CT\u WIDTH
大小,并且在每次
j
迭代后不再使用。您可以通过在
for(int j
循环和
compute\u closure
调用之间重用Ds来相同一些内存和GC时间。而不是
int[]D;/…/D=compute_closure
,预创建D并将其传递给函数:
int[]D=new int[xxx];/…/compute_closure(D,B,j)
+从
闭包中删除D的分配。我对此表示怀疑,但有点确定。请更新您的问题以解释更多关于位屏蔽的内容,好吗?我只是不理解这个
//CT\u WIDTH\u SHIFTED=(CT\u WIDTH+31)>>5
它计算存储126位所需的32位整数的数量。加31是为了确保该值向上舍入,因为这意味着结果将大一个,除非CT_宽度正好可被32整除。(126+31)/32=4(整数除法)好的,但是126不是固定的,它取决于输入有时会像4或60或200…等等,这就是为什么它是一个公式而不是硬编码的值。例如,(60+31)/32=2。(200+31)/32=7等等。
// 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];
B[j] = 1;
B[j >> 5] |= 1 << (j & 31)