昨天下午到今天下午,接近一天的时间做poi数据的分城市统计工作。
poi数据是大数据量的文本数据,数据量是千万级别,重点城市可以拿到坐标范围数据。
昨天偷懒,用python完成了一个逐条统计脚本,运行到今天早上,居然没有跑完。
产品催的紧,没办法只能用c++完成。写之前想到用并发执行统计功能。
然而启动多线程时碰到了一个小坑,伪码如下:
for (int i = 0; i < threads_num; ++i) {
std::thread loop_thread(thread_func, param1, param2);
loop_thread.join();
}
启动进程,发现cpu一直没有跑起来,只是100%,不是应该是threads_num * 100%么?
问题原来出在创建线程之后,直接执行了join操作,实际还是一个线程执行完再执行另外一个,哈哈哈。
正确的启动方式是这样的:
std::thread threads[threads_num];
for (int i = 0; i < threads_num; ++i) {
threads[i] = std::thread(thread_func, param1, param2);
}
for (int i = 0; i < threads_num; ++i) {
threads[i].join();
}
如此这般之后,cpu确实跑起来了,然而效率仍然不敢恭维。
跑小数据量的时候,10000条记录也很耗时,问题绝对出在点是否在面的范围内的判断上。
这难不倒我,我还有道格拉斯-普特。
然而dist参数的设置是个难题,只能对比之前跑出的结果,逐一调参。
经过一系列骚操作,千万级数据在10分钟内跑完了,其中时间绝大部分花在了文本数据的读取上了。
学到了:
1 c++多线程启动
2 抽稀的重要性