【问题标题】:How to increase the speed of reading csv in c++c++中如何提高读取csv的速度
【发布时间】:2021-03-19 09:02:49
【问题描述】:

我目前正在做我的项目,但整个程序浪费了太多时间。

经过一些测试,我发现程序在 I/O 上花费了太多时间。

因为每个文件都有不同的数据大小,而且我在程序中使用随机元素,所以很难提前阅读。

希望有人能帮我处理一下。

vector<string> _csv(string s)
{
    vector<string> arr;
    istringstream delim(s);
    string token;
    int c = 0;
    while (getline(delim, token, ','))
    {
        arr.push_back(token);
        c++;
    }
    return arr;
}

string filename = company[0] + "_RSI" + std::to_string(rsi[j][24]) + ".csv";
// cout << filename << endl;
ifstream inFile(".\\RSI1~256\\" + filename, ios::in);
if (!inFile) {
  cout << "Open failed!" << endl;
  exit(1);
}
string line;
while (getline(inFile, line)) {
  vector<string> a = _csv(line);
  RSI.push_back(atof(a[2].c_str()));
  price.push_back(atof(a[1].c_str()));
  date.push_back(a[0]);
}

【问题讨论】:

  • 也许尝试以二进制格式保存它?我没有这方面的经验,但可能有助于提高读写速度。
  • “程序在 I/O 上花费了太多时间”。这不是一个简单的代码修复。您显示的代码只是将数据推送到向量上。虽然重新分配(当需要调整大小时)需要时间,但对于磁盘访问来说可以忽略不计。实际上是什么问题?你想让我做什么?为什么程序“浪费太多时间”?文件访问总是需要时间。
  • 除非您向我们展示_csv 函数,否则我们无法判断。另外,请检查您测量的是发布版本时间,而不是调试版本时间。
  • 如果要进行优化,那就是尽可能多地预加载数据。也可能压缩它,而不是使用原始 CSV。
  • 尝试使用内存映射文件。

标签: c++ csv file


【解决方案1】:

对您的ifstream 使用缓冲区。至少 MSVC 实现在没有缓冲区的情况下表现不佳。

   std::vector<char> buffer(256 * 1024);
   std::ifstream inFile(".\\RSI1~256\\" + filename, std::ios::in);
   inFile.rdbuf()->pubsetbuf(buffer.data(), buffer.size());

注意 - 语句必须按照所示的确切顺序,以确保关于流的正确缓冲区寿命。

【讨论】:

    【解决方案2】:

    可能的优化:不要直接使用 CSV 文件,而是使用压缩缓存版本,一旦加载,您将使用 zlib(或 Poco.Zip 或其他)解压缩。
    根据您的平均 CSV 文件内容,这可以大大减少您需要从磁盘加载的数据量。也许您的整个数据库可以加载到 RAM 中,并在需要时选择性地解压缩一些条目。

    └── your-database/
        ├── file0001.csv
        ├── file0002.csv
        ├── ...
        └── cache/
            ├── file0001.csv.zip
            └── file0001.csv.zip
            └── ...
    

    【讨论】:

    • 解压缩也需要(很多)时间......就像将文件加载到内存中一样。也许他实际上并不需要缓存它们,而只需要读取一次。
    • 当数据不是完全随机噪声并且您的 CPU 还不错时,通常可以更快地放气 -> 存储/发送 -> 膨胀数据。
    【解决方案3】:

    首先,做一些分析,看看你在哪里花费了太多时间。

    如果您在 getline 调用上花费了太多时间,您可能需要关注如何将数据放入内存,即通过读取更大的块或使用其他技术(操作系统特定的东西、更改文件格式、使用压缩)。

    如果您在解析器上花费了很多时间,那么请考虑一下,此时您分两遍解析 CSV 文件的每一行:首先将行拆分(以一种不完全执行良好的方式) ,将所有内容写入向量,然后解析向量的每个条目。这会导致大量不必要的内存分配。您可以使用更量身定制的 _csv 函数版本,该函数使用 std::from_chars 进行解析并直接写入向量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-15
      • 2019-06-22
      • 2016-11-23
      • 1970-01-01
      • 1970-01-01
      • 2013-08-10
      • 2014-07-16
      • 2013-10-26
      相关资源
      最近更新 更多