需使用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;
}