需使用VS2017及以上版本,C++语言标准选择C++17,支持OpenMP。
执行效率明显优于ifstream + stof。
// 点云数据结构
struct PointXYZ {std::array<float, 3> coord;
};float string_to_float_fast(const std::string& str) {float value;auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value);if (ec != std::errc()) {// 处理错误(如非数字字符串)return 0.0f; // 或抛出异常}return value;
}uint8_t string_to_uchar_fast(const std::string& str) {unsigned int value;auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value);if (ec != std::errc() || value > 255) {return 0; // 错误处理}return static_cast<uint8_t>(value);
}bool read_pointcloud_parallel(const std::string& filename, std::vector<PointData>& cloud) {struct CSVRow {std::string col1, col2, col3;};// --- 1. 打开文件并内存映射 ---HANDLE hFile = CreateFileA(filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (hFile == INVALID_HANDLE_VALUE) {//throw std::runtime_error("Failed to open file");printf("Failed to open file");return false;}DWORD fileSize = GetFileSize(hFile, NULL);HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);if (hMapping == NULL) {CloseHandle(hFile);printf("Failed to create file mapping");return false;//throw std::runtime_error("Failed to create file mapping");}const char* mappedData = static_cast<const char*>(MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, fileSize));if (mappedData == NULL) {CloseHandle(hMapping);CloseHandle(hFile);throw std::runtime_error("Failed to map view of file");}// --- 2. 分块并行解析 ---std::vector<CSVRow> rows;rows.reserve(1000000); // 预分配//#pragma omp parallel{// 每个线程处理一块数据int numThreads = omp_get_num_threads();int threadId = omp_get_thread_num();size_t chunkSize = fileSize / numThreads;size_t start = threadId * chunkSize;size_t end = (threadId == numThreads - 1) ? fileSize : (threadId + 1) * chunkSize;// 调整起始位置到行首if (threadId != 0) {while (start < fileSize && mappedData[start] != '\n') start++;if (start < fileSize) start++;}// 解析当前块std::vector<CSVRow> localRows;size_t pos = start;while (pos < end) {size_t lineEnd = pos;while (lineEnd < fileSize && mappedData[lineEnd] != '\n') lineEnd++;std::string line(mappedData + pos, lineEnd - pos);pos = lineEnd + 1;// 分号分割3列size_t col1End = line.find(';');size_t col2End = line.find(';', col1End + 1);if (col3End != std::string::npos) {
//#pragma omp criticalrows.emplace_back(CSVRow{line.substr(0, col1End),line.substr(col1End + 1, col2End - col1End - 1),line.substr(col2End + 1)});}}}// --- 3. 清理资源 ---UnmapViewOfFile(mappedData);CloseHandle(hMapping);CloseHandle(hFile);cloud.resize(rows.size());
#pragma omp parallel forfor (int i = 0;i < rows.size();i++){cloud[i].coord[0] = string_to_float_fast(rows[i].col1);cloud[i].coord[1] = string_to_float_fast(rows[i].col2);cloud[i].coord[2] = string_to_float_fast(rows[i].col3);}return true;
}