【发布时间】:2019-03-07 21:54:40
【问题描述】:
问题:
给定两个固定大小的数组:
d_D = (unsigned int*)malloc(50 * 6 * sizeof(unsigned int));
C = (unsigned int*)malloc(1 * 6 * sizeof(unsigned int));
目标:
打印数组 C 中的所有数字,前提是数组 d_D 的每一行至少有一个与数组 C 相同的数字。
E.G. d_D的第一行{1,8,10,15,20,30},数组C的个数{1,2,3,4,5,6},共有1个,测试通过。 该检查进行了 50 次,并且必须通过 50 次才能打印数组 C 的数量。
寻找比提供的代码更快的方法。
提供的代码是第一个数组的每一行和第二个数组的唯一行之间的交集。交集进行了五十次,如果五十个交点中的每一个都返回一个公共数字,它将打印第二个数组的六个数字。整个程序的核心是一个循环,它将第一个数组的每一行的每个数字与第二个数组的唯一一行的每个数字进行比较,所以即使没有六个数字的 printf,并且用 break 而不是转到未找到的标签,循环仍将进行交叉。代码也被调用了五千万次
我尝试了单数组和多维数组的组合,结果发现多维数组更快。
这是我想出的最快方法: 链接到整个程序以再次进行基准测试:https://onlinegdb.com/B159y4vcQ
你可以去上面的链接添加你的版本,看看你能不能做得更好。
// Iterate through all the rows of array d_D: 1 to 50
for (i = 0; i < 50; i++)
{
// Compare the first number of array C against all the numbers of array d_D row i
if ((d_D[i * 6 + 0] == C[0 * 6 + 0]) || (d_D[i * 6 + 1] == C[0 * 6 + 0]) || (d_D[i * 6 + 2] == C[0 * 6 + 0]) || (d_D[i * 6 + 3] == C[0 * 6 + 0]) || (d_D[i * 6 + 4] == C[0 * 6 + 0]) || (d_D[i * 6 + 5] == C[0 * 6 + 0]))
{
goto NextFilter;
}
// Compare the second number of array C against all the numbers of array d_D row i
if ((d_D[i * 6 + 0] == C[0 * 6 + 1]) || (d_D[i * 6 + 1] == C[0 * 6 + 1]) || (d_D[i * 6 + 2] == C[0 * 6 + 1]) || (d_D[i * 6 + 3] == C[0 * 6 + 1]) || (d_D[i * 6 + 4] == C[0 * 6 + 1]) || (d_D[i * 6 + 5] == C[0 * 6 + 1]))
{
goto NextFilter;
}
// Compare the third number of array C against all the numbers of array d_D row i
if ((d_D[i * 6 + 0] == C[0 * 6 + 2]) || (d_D[i * 6 + 1] == C[0 * 6 + 2]) || (d_D[i * 6 + 2] == C[0 * 6 + 2]) || (d_D[i * 6 + 3] == C[0 * 6 + 2]) || (d_D[i * 6 + 4] == C[0 * 6 + 2]) || (d_D[i * 6 + 5] == C[0 * 6 + 2]))
{
goto NextFilter;
}
// Compare the fourth number of array C against all the numbers of array d_D row i
if ((d_D[i * 6 + 0] == C[0 * 6 + 3]) || (d_D[i * 6 + 1] == C[0 * 6 + 3]) || (d_D[i * 6 + 2] == C[0 * 6 + 3]) || (d_D[i * 6 + 3] == C[0 * 6 + 3]) || (d_D[i * 6 + 4] == C[0 * 6 + 3]) || (d_D[i * 6 + 5] == C[0 * 6 + 3]))
{
goto NextFilter;
}
// Compare the fifth number of array C against all the numbers of array d_D row i
if ((d_D[i * 6 + 0] == C[0 * 6 + 4]) || (d_D[i * 6 + 1] == C[0 * 6 + 4]) || (d_D[i * 6 + 2] == C[0 * 6 + 4]) || (d_D[i * 6 + 3] == C[0 * 6 + 4]) || (d_D[i * 6 + 4] == C[0 * 6 + 4]) || (d_D[i * 6 + 5] == C[0 * 6 + 4]))
{
goto NextFilter;
}
// Compare the sixth number of array C against all the numbers of array d_D row i
if ((d_D[i * 6 + 0] == C[0 * 6 + 5]) || (d_D[i * 6 + 1] == C[0 * 6 + 5]) || (d_D[i * 6 + 2] == C[0 * 6 + 5]) || (d_D[i * 6 + 3] == C[0 * 6 + 5]) || (d_D[i * 6 + 4] == C[0 * 6 + 5]) || (d_D[i * 6 + 5] == C[0 * 6 + 5]))
{
goto NextFilter;
}
goto notfound;
NextFilter:
;
}
// Print the six numbers of array C if all the rows of array d_D have at least one number in common with array C
printf("%d %d %d %d %d %d\n", C[0 * 6 + 0], C[0 * 6 + 1], C[0 * 6 + 2], C[0 * 6 + 3], C[0 * 6 + 4], C[0 * 6 + 5]);
notfound:
;
这是做同样事情的另一种方式,但需要双倍的时间: https://onlinegdb.com/rk97kq_9Q
for (unsigned int i = 0; i < 50; i++)
{
unsigned int i0 = 0, j0 = 0;
while (i0 < 6 && j0 < 6)
{
if (d_D[i * 6 + i0] < C[0 * 6 + j0])
i0++;
else if (C[0 * 6 + j0] < d_D[i * 6 + i0])
j0++;
else // if equal
{
goto NextFilter;
}
}
goto notfound;
NextFilter:
;
}
printf("%d %d %d %d %d %d\n", C[0 * 6 + 0], C[0 * 6 + 1], C[0 * 6 + 2], C[0 * 6 + 3], C[0 * 6 + 4], C[0 * 6 + 5]);
notfound:
;
附: GOTO 的原因是我正在展开 cuda 实现的循环,所以 continue 不是一个选项,但在这里,我必须循环,否则代码会太长。
【问题讨论】:
-
如果不必要的二维数组
C[1][6]是一维数组C[6]可能会更快,尽管编译器可能会优化。无论如何d_D[i * 6 + 0] == C[1]是垃圾。你不能像那样比较整个数组,C[1]也打破了数组界限。 -
抱歉打错了,其实是C[0],C[1],C[2],C[3],C[4],C[5] or C[0 * 6 + 0]、C[0 * 6 + 1] 等等
-
让编译器做优化。您的叙述
C[1][6]与代码不符(现已编辑)。请发布显示问题的Minimal, Complete, and Verifiable example。无论如何else比goto好。 -
Fastest 没有什么意义,除非代码被重复调用。如果经常调用,二维数组和一维数组是否总是相同的大小?可能的数组大小是多少?如果二维数组的一维匹配一维?一维数组值是否不变而其他二维数组值不变?还是反之亦然?值的范围是多少 - 完整的 `int 范围?为了获得最快的代码,这些问题需要随着方法的变化而回答。没有更多信息,这篇文章太宽泛了。更好的是,发布你的代码的测试工具,其他人可以插入他们的代码并比较时间。
-
标题中问题的答案是“是”。如果您需要更详细的答案,则需要在问题中添加更多详细信息。
标签: c arrays algorithm performance