【发布时间】:2018-10-13 23:46:25
【问题描述】:
我有一组原始数据文件,每个文件有 800 万~900 万行(是的, 8,000,000~9,000,000),格式如下,
1,2,3,4,5,16,23,35
1,2,3,4,6,17,23,36
1,2,3,4,7,18,23,37
1,2,3,4,8,19,23,38
1,2,3,4,9,20,23,39
1,2,3,4,10,21,23,40
1,2,3,4,11,22,23,41
1,2,3,4,12,23,24,42
1,2,3,4,13,24,25,43
1,2,3,4,14,25,26,44
每行有 8 个排序后的数字,范围为 1~49。 另一组“过滤器”文件,每个文件有 600 万到 700 万行 以下格式,
13,4,7,8,18,20
9,10,11,12,5,6,7,8,1,2,3,4,21,22,23,24,13,14,15,16,29,30,31,32,45,46,47,48
29,49,36,37,34,17,15,9,16,30,28,47,46,27,20,32,14,26,1,4,3,6,10,2,7,48,44,41
每行有 4~28 个未排序的数字,范围为 1~49 我需要将“原始数据”文件中的每一行与“过滤器”文件中的每一行进行比较 并获得交点值,例如raw 中的第 1 行,filter 中的第 1~3 行
1 // since only 4 is in common with filter line 1
7 // since only 35 not found in filter line 2
6 // since 5 23 35 not found in filter line 3
比较后,会根据阈值输出结果。 例如
output raw data line with intersection value >= 2,
output raw data line with intersection value == 4
我知道(最多)有 900 万 x 800 万行比较。 起初,我尝试使用 set_intersection 来完成这项工作,但完成这项任务需要很长时间(过滤线在传递给 set_intersection 之前已排序)。
int res[8];
int *it = set_intersection(Raw.Data, Raw.Data+8, FilterVal.begin(), FilterVal.end(), res);
ds = GetIntersect(GDE.DrawRes, LotArr) * 2;
int IntersectCnt=it-res;
接下来,我尝试构建一个整数零数组:
int ResArr[49] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
并使用 3 个辅助函数:
void InitResArr(int * inResArr, vector<int> & FilterVal) {
for (int i = 0; i < FilterVal.size(); i++) {
inResArr[FilterVal[i] - 1] = 1;
}
}
void ResetResArr(int * inResArr, vector<int> & FilterVal) {
for (int i = 0; i < FilterVal.size(); i++) {
inResArr[FilterVal[i] - 1] = 0;
}
}
int GetIntersect(int * inResArr, int * inRawData) {
int RtnVal = 0;
for (int i = 0; i < 8; i++) {
RtnVal+=inResArr[inRawData[i] - 1];
}
但是这种方法仍然需要 3 个小时以上才能完成 1 个比较(1 个原始数据文件和 1 个过滤器)。 我还有 5,000 个原始数据文件和 40,000 个过滤器要处理!!! 有没有其他更好的方法来处理这个任务?谢谢。
注册表
林志峰
【问题讨论】:
-
如果过滤器也被排序会有所帮助,也许您可以将其添加为预处理步骤
-
考虑使用位域——您只有 0 到 49 范围内的数字,因此 64 位整数足以编码每行的所有可能值。交集将是按位与。交集的基数是popcount。
-
我建议你分析你的代码并找出你的瓶颈到底是哪一部分。
-
老兄!您至少有 8e6 行可以与其他 6e6 行进行比较。这意味着 48e12 比较!即使每次比较需要 1ns=1e-9s,你也需要 48e3s,大约是 13h。我很惊讶你能做到 3 小时!
-
另外,这是高度可并行化的,所以如果你有一个多核系统,你可能会考虑这个。
标签: c++ arrays vector intersection