gpt4 book ai didi

c++ - 如何 boost 大型 txt 处理脚本的速度?

转载 作者:行者123 更新时间:2023-12-02 01:48:44 25 4
gpt4 key购买 nike

我有一个程序可以扫描一个非常大的 txt 文件 ( .pts file actually ),如下所示:

437288479
-6.9465 -20.49 -1.3345 70
-6.6835 -20.82 -1.3335 83
-7.3105 -20.179 -1.3325 77
-7.1005 -20.846 -1.3295 96
-7.3645 -20.759 -1.2585 79
...

第一行是文件中包含的点的数量,每隔一行对应 3D 空间中的一个 {x,y,z,intensity} 点。上面的文件大小为 ~11 GB,但我还有更多文件需要处理,最大可达 ~50 GB

这是我用来读取此文件的代码:

#include <iostream>
#include <chrono>
#include <vector>
#include <algorithm>
#include <tuple>
#include <cmath>

// boost library
#include <boost/iostreams/device/mapped_file.hpp>
#include <boost/iostreams/stream.hpp>

struct point
{
double x;
double y;
double z;
};


void readMappedFile()
{
boost::iostreams::mapped_file_source mmap("my_big_file.pts");
boost::iostreams::stream<boost::iostreams::mapped_file_source> is(mmap, std::ios::binary);
std::string line;

// get rid of the first line
std::getline(is, line);

while (std::getline(is, line))
{
point p;
sscanf(line.c_str(),"%lf %lf %lf %*d", &(p.x), &(p.y), &(p.z));
if (p.z > minThreshold && p.z < maxThreshold)
{
// do something with p and store it in the vector of tuples
// O(n) complexity
}
}
}

int main ()
{
readMappedFile();
return 0;
}

对于我的 11 GB 文件,扫描所有行并将数据存储在 p 点 需要 ~13 分钟 来执行。有没有办法让它变得更快?因为每次我扫描一个点时,我也必须用它做一些事情。这将使我的程序最终需要几个小时才能执行。

我开始考虑使用多个核心,但如果某些点由于某种原因链接在一起,似乎可能会出现问题。如果您对如何进行有任何建议,我很乐意听取。

Edit1:我在笔记本电脑上运行该程序,其 CPU 包含 8 核 - 2.9GHz,内存为 16GB,我使用的是 SSD。为此,程序必须在类似的硬件上运行。

Edit2:这是完整的程序,这样你就可以告诉我我做错了什么。我将每个点定位在一种称为 slab 的 2D 网格中。每个单元格将包含一定数量的点和一个 z 平均值。

#include <iostream>
#include <chrono>
#include <vector>
#include <algorithm>
#include <tuple>
#include <cmath>

// boost library
#include <boost/iostreams/device/mapped_file.hpp>
#include <boost/iostreams/stream.hpp>

struct point
{
double x;
double y;
double z;
};

/*
Compute Slab
*/

float slabBox[6] = {-25.,25.,-25.,25.,-1.,0.};
float dx = 0.1;
float dy = 0.1;
int slabSizeX = (slabBox[1] - slabBox[0]) / dx;
int slabSizeY = (slabBox[3] - slabBox[2]) / dy;

std::vector<std::tuple<double, double, double, int>> initSlab()
{
// initialize the slab vector according to the grid size
std::vector<std::tuple<double, double, double, int>> slabVector(slabSizeX * slabSizeY, {0., 0., 0., 0});

// fill the vector with {x,y} cells coordinates
for (int y = 0; y < slabSizeY; y++)
{
for (int x = 0; x < slabSizeX; x++)
{
slabVector[x + y * slabSizeX] = {x * dx + slabBox[0], y * dy + slabBox[2], 0., 0};
}
}
return slabVector;
}

std::vector<std::tuple<double, double, double, int>> addPoint2Slab(point p, std::vector<std::tuple<double, double, double, int>> slabVector)
{
// find the region {x,y} in the slab in which coord {p.x,p.y} is
int x = (int) floor((p.x - slabBox[0])/dx);
int y = (int) floor((p.y - slabBox[2])/dy);

// calculate the new z value
double z = (std::get<2>(slabVector[x + y * slabSizeX]) * std::get<3>(slabVector[x + y * slabSizeX]) + p.z) / (std::get<3>(slabVector[x + y * slabSizeX]) + 1);

// replace the older z
std::get<2>(slabVector[x + y * slabSizeX]) = z;

// add + 1 point in the cell
std::get<3>(slabVector[x + y * slabSizeX])++;
return slabVector;
}

/*
Parse the file
*/

void readMappedFile()
{
boost::iostreams::mapped_file_source mmap("my_big_file.pts");
boost::iostreams::stream<boost::iostreams::mapped_file_source> is(mmap, std::ios::binary);

std::string line;
std::getline(is, line);

auto slabVector = initSlab();

while (std::getline(is, line))
{
point p;
sscanf(line.c_str(),"%lf %lf %lf %*d", &(p.x), &(p.y), &(p.z));
if (p.z > slabBox[4] && p.z < slabBox[5])
{
slabVector = addPoint2Slab(p, slabVector);
}
}
}

int main ()
{
readMappedFile();
return 0;
}

最佳答案

如果您使用 HDD 存储文件,仅以 100Mb/s 的速度读取将花费约 2 分钟,这是一个很好的情况。尝试读取文件的一个 block 并在另一个线程中处理它,同时下一个 block 将被读取。

此外,您还有类似的内容:

std::vector<...> addPoint2Slab(point, std::vector<...> result)
{
...
return result;
}

slabVector = addPoint2Slab(point, slabVector);

我想它会在每次调用时带来不必要的slabVector复制(实际上,编译器可能会优化它)。如果您传递 vector ,请尝试检查速度,如下所示:

std::vector<...> addPoint2Slab(point, std::vector<...> & result);

并调用:

addPoint2Slab(point, slabVector);

如果它会获得速度奖励,您可以检查如何在没有开销的情况下转发结果。

关于c++ - 如何 boost 大型 txt 处理脚本的速度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70594385/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com