c++ - 如何加速包含图形数据的文本文件的 io/解析

标签 c++ parsing io ifstream

所以我有这个任务要实现 A* 算法,但是我从文件中读取图形节点数据的速度非常慢,大约需要 4 分钟,我想知道是否有办法显着加快速度.

(kart对象只是一个节点 vector ,本题重点是io)

ifstream ifs_edge("<my path>", ios::binary | ios::ate);
    auto edges_size = ifs_edge.tellg();
    ifs_edge.seekg(ios::beg);
    string str_edges(edges_size, 0);
    ifs_edge.read(&str_edges[0], edges_size);
    cout << edges_size << endl;

    int counter = 0;
    double lon = 0, lat = 0;
    string substr;
    for (char c : str_edges)
    {
            if (c != 0x20 && c != 0x0A)
                    substr += c;
            else
            {
                    if (substr.size())
                    {
                            if (counter == 1)
                                    lon = stod(substr);
                            if (counter == 2)
                                    lat = stod(substr);
                            substr.clear();
                            counter++;
                    }
            }
            if (c == 0x0A)
            {
                    counter = 0;
                    if (lon && lat)
                    {
                            astar::kart_node kn;
                            kn.c = { lon, lat };
                            kart.push_back(kn);
                    }
            }
    }

编辑:问题文件的结构如下: 第一行=节点数,后面是[index] [longitude] [latitude]

    3901630
0 55.6345147 12.0729268
1 55.6345880 12.0722614
2 55.6346358 12.0705787
3 55.6390838 12.0686184

编辑 2: 已经提供了更快的解决方案,这很好,但由于某些奇怪的原因,它对我来说太慢了,我也尝试了几台计算机。谜团仍然存在,我愿意接受更多建议,即使我的解决方案已得到改进,问题也不会被标记为已解决。

最佳答案

由于您的数据是标准化的,因此您可以使用 fstream 或 fscanf。

这是输出: fstream大约需要7.2s fscanf 大约需要 1.6s

Reading from data.txt
1000000 entry read!
2000000 entry read!
3000000 entry read!
last entry: -116.239,89.5744
read_file_cpp 7.19992s
1000000 entry read!
2000000 entry read!
3000000 entry read!
last entry: -116.239,89.5744
read_file_c 1.55708s

这是代码,用 clang++ -O3 编译

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cmath>
#include <ctime>
#include <cstdio>
using namespace std;

void read_file_cpp(const string& path, vector<pair<double, double> >* kart) {
  ifstream in(path);
  int n, index;
  double lon, lat;
  in >> n;
  for (int i=1;i<=n;++i) {
    in >> index >> lon >> lat;
    kart->push_back(make_pair(lon, lat));
    if(i % 1000000 == 0)
      cout << i << " entry read!" <<endl;
  }

  in.close();
}

void read_file_c(const string& path, vector<pair<double, double> >* kart) {
  FILE* f = fopen(path.c_str(),"r");
  int n, index;
  fscanf (f, "%d", &n);
  double lon, lat;

  for (int i=1;i<=n;++i) {
    fscanf(f, "%d %lf %lf", &index, &lon, &lat);
    kart->push_back(make_pair(lon, lat));
    if(i % 1000000 == 0)
      cout << i << " entry read!" <<endl;
  }

  fclose(f);
}

void generate_data(const string& path, int n) {

  cout << "generating data... " << endl;

  ofstream out(path);
  out << n << endl;
  for (int i=0;i<n;++i) {
    float lon = static_cast <float> (rand()) / static_cast <float> (RAND_MAX) * 360 - 180;
    float lat = static_cast <float> (rand()) / static_cast <float> (RAND_MAX) * 360 - 180;
    out << i << " " << lon << " " << lat << endl;
  }
  out.close();

  cout << "done !" << endl;
}


int main() {
  const string path = "data.txt";
  vector<pair<double, double> > data;

  // generate_data(path, 3901630);
  {
    clock_t begin = clock();
    read_file_cpp(path, &data);
    clock_t end = clock();
    double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;

    cout << "last entry: " << data.back().first << "," << data.back().second << endl;

    cout << "read_file_cpp "<< elapsed_secs << "s" << endl;
  }

  data.clear();

  {
    clock_t begin = clock();
    read_file_c(path, &data);
    clock_t end = clock();
    double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;

    cout << "last entry: " << data.back().first << "," << data.back().second << endl;

    cout << "read_file_c "<< elapsed_secs << "s" << endl;
  }

}

关于c++ - 如何加速包含图形数据的文本文件的 io/解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40595806/

相关文章:

java - Telnet基本IO操作

java - 文件 I/O 在输出中产生乱码

C++包含头文件

c++ - 从文件中读取整数 - 逐行

c# - 在 XML 命名空间中插入和删除节点

linux - 括号和 ips 之间的所有内容都解析失败

c - 字符串解析,纯C

python - 模块 VTK 无法在 Windows 上读取 Python3 中的文件

c++ - 在 Qt Creator 中使用我自己的函数的自动文档?

c++ - libSDL、CMake 和 Mac OS X Lion