【发布时间】:2017-12-01 13:48:51
【问题描述】:
我正在尝试计算 (n x n) 乘法表中唯一条目的数量。
(12x12) 乘法表:
× 1 2 3 4 5 6 7 8 9 10 11 12
1 1 2 3 4 5 6 7 8 9 10 11 12
2 2 4 6 8 10 12 14 16 18 20 22 24
3 3 6 9 12 15 18 21 24 27 30 33 36
4 4 8 12 16 20 24 28 32 36 40 44 48
5 5 10 15 20 25 30 35 40 45 50 55 60
6 6 12 18 24 30 36 42 48 54 60 66 72
7 7 14 21 28 35 42 49 56 63 70 77 84
8 8 16 24 32 40 48 56 64 72 80 88 96
9 9 18 27 36 45 54 63 72 81 90 99 108
10 10 20 30 40 50 60 70 80 90 100 110 120
11 11 22 33 44 55 66 77 88 99 110 121 132
12 12 24 36 48 60 72 84 96 108 120 132 144
现在,'ans' 数组的第 n 个元素包含 (n x n) 乘法表中的唯一条目数。
我注意到访问大型 'mark' 数组的元素需要很长时间。虽然如果我每次都访问一个元素不会花费太多时间。
现在我的代码需要大约 12-13 秒来完成构建“ans”数组。我可以进一步优化它,使其大约需要 5 秒吗?
#include <stdio.h>
#define MAX 30000
char mark[(MAX*MAX) + 1];
int ans[MAX+1];
void calc(){
int i, j, cnt = 0, x;
ans[0] = 0;
for (i = 1; i <= MAX; i++){
for (j = 1; j <= i; j++){
x = i*j;
if (!mark[x]){
mark[x] = 1;
cnt++;
}
}
ans[i] = cnt;
}
}
int main(){
calc();
printf("ans[%d] = %d\n", MAX, ans[MAX]);
/*
int n, t;
scanf("%d", &t);
while (t--){
scanf("%d", &n);
printf("%d\n", ans[n]);
}
*/
return 0;
}
编辑:我正在尝试计算 (n x n) 表中唯一条目的数量。建立表格不是这里的主要目标。我正在使用“标记”数组来检查新号码是否唯一。如果没有数组,我想不出任何其他方法。我尝试使用矢量位,它有助于降低内存,但需要更多时间。代码中真正慢的部分是访问数组元素。对于 n = 30k,每次都有很大的进步。没有内存访问部分-
if (!mark[x]){
mark[x] = 1;
cnt++;
}
完成程序只需大约 1 秒。但我想不出任何改变访问模式的方法。
如果我只是想找出 (30k x 30k) 表中的唯一条目,我可以像这样更改访问模式-
1
2 4
3 6 9
4 8 12 16
5 10 15 20 25
目前,我们从头到尾(从左到右)检查每一行
我们可以接近每一列(从上到下)
int lim = 1;
for (i = 1; i <= MAX; i++){
lim += MAX;
for (j = i*i; j <= lim; j+= i){
if (!mark[j]){
mark[j] = 1;
cnt++;
}
}
//ans[i] = cnt;
}
ans[MAX] = cnt;
因此,访问内存的步幅变小了。在我的 PC 中,代码在大约 9 秒(少约 3 秒)内完成。但我正在尝试为每个 (n x n) 表获取答案。
【问题讨论】:
-
12x12 乘法表根本不值得存储在内存中。只需在打印时即时计算条目.... ups 误读,但如果是 100 万 x 100 万,那么更多的 cpu 会胜过内存
-
您尝试过优化构建吗?
-
这个程序的慢部分是 printf() ...正如@tobi303 所说,它不值得记忆。进行计算的额外周期将花费您 1000 秒。但可以为您节省 8000 GB 的内存(需要长整数,而不仅仅是整数)。即使您可以存储其中的一小部分,RAM 成本也不值得
-
@UKMonkey 我不明白你是如何得出这个 sn-p 需要 8000 GB 的结论的。
-
@FrançoisAndrieux 你是对的 - 我读了 tobis 的回复并错过了 OP 的 30,000 所以它是 4(int) * 30,000 * 30,000 = 14G ...仍然比我愿意投资的 RAM 多在乘法表中
标签: c++ arrays algorithm performance optimization