当前位置: 首页 > news >正文

C++高效读取大规模文本格式点云(windows)

需使用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 critical
				rows.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 for
	for (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;
}

相关文章:

  • 手机归属地查询Api接口,数据准确可靠
  • 根据时间范围得出雪花算法(snowflake)ID的工具类-基于时间反推ID范围
  • AiCube 试用 - 创建流水灯工程
  • 有瓶颈设备的多级生产计划问题:基于Matlab的深度解析与实践
  • LeetCode 解题思路 31(Hot 100)
  • 八. 深入理解 Java 继承:概念、应用与最佳实践
  • Error:java: 程序包lombok不存在
  • 基于springboot+vue的停车场管理系统
  • 数据库 第一章 MYSQL基础(5)
  • 在线Notepad智能笔记——你的全能AI创作助手
  • C++ 常量
  • 【gdutthesis模板】章节标题有英文解决方案
  • 数据结构第一轮复习--第六章图包含代码
  • 蓝桥杯冲刺
  • Mybatis模糊查询
  • 【C语言】字符串处理指南
  • 容器的CPU
  • T n、const T n、T const n
  • 1. hadoop 集群的常用命令
  • 工商业储能要关注的核心能力与未来发展方向