如何在读取文件时获得更高的性能

How to get more performance when reading file

本文关键字:性能 读取 文件      更新时间:2023-10-16

我的程序从网站下载文件(通过curl每30分钟)。(这些文件的大小有可能达到150mb)

所以我认为从这些文件中获取数据可能是低效的。(每5秒搜索一行)

这些文件可以有~ 10,000行

要解析这个文件(值之间用","分隔),我使用regex:

regex wzorzec("(.*),(.*),(.*),(.*),(.*),(.*),(.*),(.*)");

有8个值

现在我要把它压入vector:

allys.push_back({ std::stoi(std::string(wynik[1])), nick, tag, stoi(string(wynik[4])), stoi(string(wynik[5])), stoi(string(wynik[6])), stoi(string(wynik[7])), stoi(string(wynik[8])) });

我使用std::async来做到这一点,但是对于3个文件(~ 7mb),处理器跳到80%,操作大约需要10秒。我从SSD读取,所以这不是缓慢的IO故障。我正在逐行读取fstream

的数据

如何增强此操作?也许我必须解析这个值,并把它推到SQL ?

您可能会通过避免regex而使用std::strtok之类的东西来获得一些性能提升,或者只是硬编码在数据中搜索逗号。Regex具有比查找逗号更强大的功能。接下来,如果在对任何给定的向量开始push_back序列之前使用vector::reserve,则可以在重新分配和移动内存方面节省大量时间。如果你期待一个大的向量,提前为它预留空间。

这可能没有涵盖所有可用的性能想法,但我敢打赌您将看到改进。

这里的问题很可能是正则表达式引入的额外开销,因为您使用了许多可变长度和贪婪匹配(regex引擎将尝试不同的匹配方式以找到最大的匹配结果)。

相反,您可能希望尝试手动解析这些行。有许多不同的方法可以做到这一点。这里有一个简单的示例(它不灵活,并且其中有相当多的重复代码,但有很多优化空间)。但它应该解释基本思想:

#include <iostream>
#include <sstream>
#include <cstdlib>
const char *input = "1,Mario,Stuff,4,5,6,7,8";
struct data {
    int id;
    std::string nick;
    std::string tag;
} myData;
int main(int argc, char **argv){
    char buffer[256];
    std::istringstream in(input);
    // Read an entry and convert/store it:
    in.get(buffer, 256, ','); // read
    myData.id = atoi(buffer); // convert and store
    // Skip the comma
    in.seekg(1, std::ios::cur);
    // Read the next entry and convert/store it:
    in.get(buffer, 256, ','); // read
    myData.nick = buffer; // store
    // Skip the comma
    in.seekg(1, std::ios::cur);
    // Read the next entry and convert/store it:
    in.get(buffer, 256, ','); // read
    myData.tag = buffer; // store
    // Skip the comma
    in.seekg(1, std::ios::cur);
    // Some test output
    std::cout << "id: " << myData.id << "nnick: " << myData.nick << "ntag: " << myData.tag << std::endl;
    return 0;
}

请注意,如果条目太长或太短(或以其他方式中断),则不会有任何错误处理。

控制台输出

:

id: 1
nick: Mario
tag: Stuff