C++下优化OHLCV格式CSV文件上传速度的技术问询
我实现了一个用于存储时间序列OHLCV的类,该类包含解析文件的相关方法。当前需将约4万行的CSV文件内容上传至std::unordered_map<std::string, OHLCV>中,CSV列结构固定:datetime(std::string)、open(float)、high(float)、low(float)、close(float)、volume(float)。
现有upload方法通过std::ifstream逐行读取,用stringstream分割字段,转换后存入类内的vector容器。在开启-O2速度优先优化的Release模式下,测试耗时约328-345ms,但Python的Pandas处理同类文件仅需约63ms。请问在不使用编译期固定长度std::array的前提下,能否提升上传速度?
一次性读取整个文件到内存
逐行调用std::ifstream会产生频繁的系统IO调用,开销极高。改为一次性将整个文件读取到内存缓冲区(比如std::string或堆分配的字符数组),后续所有解析操作都在内存中完成,彻底消除IO等待的瓶颈。替换
stringstream为手动字段分割stringstream的设计偏向通用场景,逐行创建会产生大量临时对象和内存分配。可以手动遍历内存中的字符序列,根据逗号分隔符直接定位每个字段的起始和结束位置,跳过不必要的内存拷贝和对象构造,大幅提升分割效率。替换
std::stof为轻量浮点数解析函数
标准库的std::stof包含很多边界处理和兼容性逻辑,性能并非最优。可以实现一个针对CSV场景的简化浮点数解析函数,直接从字符序列转换为float,减少分支判断和内存操作,提升转换速度。预分配容器内存
已知文件约4万行,提前给std::vector调用reserve(40000),给std::unordered_map调用reserve(40000),避免插入过程中频繁的内存扩容和数据拷贝,减少内存分配开销。优化字符串的内存操作
解析datetime字段时,直接构造std::string并通过移动语义存入unordered_map的键中,避免不必要的字符串拷贝。如果使用C++17及以上,可先用std::string_view临时定位字段,再构造字符串,减少中间内存操作。优化
std::unordered_map的哈希性能
默认的std::string哈希函数针对通用场景设计,对于datetime这类格式固定的字符串,可以自定义哈希函数(比如利用固定长度的字符序列直接计算哈希值),减少哈希冲突,提升unordered_map的插入和查找效率。关闭IO同步
在打开文件前,调用std::ios_base::sync_with_stdio(false);关闭C++和C标准IO的同步,同时调用std::cin.tie(nullptr);解绑cin和cout,提升std::ifstream的读取速度。
内容的提问来源于stack exchange,提问作者solid

