Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何优化C++;将文件逐行读取到向量中? 我惊讶地发现,下面的C++只读取一个大的文件行,将这些行存储到一个向量中,输出的向量大小比Python对应的运行速度慢。如何优化它?谢谢 #include <fstream> #include <iostream> #include <vector> #include <string> int main () { std::ifstream infile("longfile.txt"); std::string line; std::vector<std::string> lines; while (std::getline(infile, line)) { lines.push_back(line); } std::cout << lines.size() << std::endl; return 0; }_Python_C++_Optimization_Stream - Fatal编程技术网

如何优化C++;将文件逐行读取到向量中? 我惊讶地发现,下面的C++只读取一个大的文件行,将这些行存储到一个向量中,输出的向量大小比Python对应的运行速度慢。如何优化它?谢谢 #include <fstream> #include <iostream> #include <vector> #include <string> int main () { std::ifstream infile("longfile.txt"); std::string line; std::vector<std::string> lines; while (std::getline(infile, line)) { lines.push_back(line); } std::cout << lines.size() << std::endl; return 0; }

如何优化C++;将文件逐行读取到向量中? 我惊讶地发现,下面的C++只读取一个大的文件行,将这些行存储到一个向量中,输出的向量大小比Python对应的运行速度慢。如何优化它?谢谢 #include <fstream> #include <iostream> #include <vector> #include <string> int main () { std::ifstream infile("longfile.txt"); std::string line; std::vector<std::string> lines; while (std::getline(infile, line)) { lines.push_back(line); } std::cout << lines.size() << std::endl; return 0; },python,c++,optimization,stream,Python,C++,Optimization,Stream,Python: with open('longfile.txt') as f: lines = f.readlines() print len(lines) 运行: 如果您可以提前知道必须读取的行数,则可以在std::vector对象中保留行数。 假设你有10行要读: int main () { std::ifstream infile("longfile.txt"); std::string line; std::vector<std::stri

Python:

with open('longfile.txt') as f:
    lines = f.readlines()

print len(lines)
运行:


如果您可以提前知道必须读取的行数,则可以在
std::vector
对象中保留行数。 假设你有10行要读:

   int main () {
    std::ifstream infile("longfile.txt");
    std::string line;
    std::vector<std::string> lines;

    lines.reserve(10);

    while (std::getline(infile, line)) {
        lines.push_back(line);
    }

    std::cout << lines.size() << std::endl;

    return 0;
}
作者:

默认情况下,对于STL中的大多数容器,复制构造函数或赋值操作符的调用将对数据进行完全复制。
std::move
防止此类复制

您可以通过以下示例轻松检查它:

std::string a("Hello");
std::string b(a);

std::cout<<a.size()<<" "<<b.size()<<std::endl;
std::cout<<"the address of a is : "<<a.c_str()<<" "<<b.c_str()<<std::endl;

std::string d(std::move(a));

std::cout<<a.size()<<" "<<d.size()<<std::endl;

std::string e;
std::string f;

e = b;

std::cout<<e.size()<<" "<<b.size()<<std::endl;
std::cout<<"the address of a is : "<<e.c_str()<<" "<<b.c_str()<<std::endl;


f = std::move(b);

std::cout<<f.size()<<" "<<b.size()<<std::endl;
std::字符串a(“你好”);
std::字符串b(a);

std::cout如果您可以提前知道必须读取的行数,则可以在
std::vector
对象中保留行数。 假设你有10行要读:

   int main () {
    std::ifstream infile("longfile.txt");
    std::string line;
    std::vector<std::string> lines;

    lines.reserve(10);

    while (std::getline(infile, line)) {
        lines.push_back(line);
    }

    std::cout << lines.size() << std::endl;

    return 0;
}
作者:

默认情况下,对于STL中的大多数容器,复制构造函数或赋值操作符的调用将对数据进行完全复制。
std::move
防止此类复制

您可以通过以下示例轻松检查它:

std::string a("Hello");
std::string b(a);

std::cout<<a.size()<<" "<<b.size()<<std::endl;
std::cout<<"the address of a is : "<<a.c_str()<<" "<<b.c_str()<<std::endl;

std::string d(std::move(a));

std::cout<<a.size()<<" "<<d.size()<<std::endl;

std::string e;
std::string f;

e = b;

std::cout<<e.size()<<" "<<b.size()<<std::endl;
std::cout<<"the address of a is : "<<e.c_str()<<" "<<b.c_str()<<std::endl;


f = std::move(b);

std::cout<<f.size()<<" "<<b.size()<<std::endl;
std::字符串a(“你好”);
std::字符串b(a);

几乎任何优化问题的答案都是“首先,配置文件”。配置你的C++应用程序并确定时间在哪里。 尽管如此,我仍然可以对这里的速度慢做出一些有根据的猜测,并指出这将如何显示在分析器中

慢速getline()
getline()
可能以缓慢的方式实现。例如,它可能需要一次向运行时请求一个字符,因为一旦看起来是换行符,它就需要停止读取。也就是说,它不能在更大的块中请求字节,因为当块的中间出现换行符时,它不能保证“回退”其余块。

运行时几乎肯定会缓冲底层文件的读取,因此这不会像每个字符一次系统调用那么糟糕,但是为文件中的每个字符有效地调用
getc
的开销仍然很大

这将在探查器中显示为花费大量时间在
getline()
-中,特别是在getline调用的一些类似
getc()
-的方法中

python实现根本没有这个问题,因为只进行了一个
readlines()
调用,并且实现知道整个文件将被读取,并且可以随意缓冲

冗余复制 另一个可能的候选者是重复复制

第一次运行时调用
read()
并将文件块复制到内部缓冲区中。然后,
getline()
实现可能会有一个
char[]
的内部缓冲区,它在将字符串传递给
string
构造函数之前构建字符串,这可能会生成另一个副本(除非运行时使用内部技巧直接传递缓冲区)

然后,正如Johnny_指出的,当你把这些字符串放入向量时,可能会有更多的副本

这将在向量中显示,因为所花费的时间分布在上述各种副本中,例如在
string()
构造函数中

实现Python还可以避免大部分冗余副本,因为它具有更高层次的问题视图,而不是C++实现中的分层方法,因此它只可能生成1或2个副本。 解决 这里提到的解决方案解决了上述两个问题。要重新实现Python

readlines
调用,您应该降低一点级别。以
char[]
为单位读取文件,并直接在缓冲区中查找换行符。从技术上讲,您根本不需要创建
string
对象,因为您只输出找到的行数,但如果确实要创建这些对象,请确保只将
char[]
数据复制到每个字符串中一次


您可以使用
字符串(const char*s,size\t n)
构造函数直接指向字符缓冲区来完成此操作。最后,正如Johnny_建议的那样,确保在复制到向量中时不要再复制另一个副本。

几乎任何优化问题的答案都是“首先,配置文件”。配置你的C++应用程序并确定时间在哪里。 尽管如此,我仍然可以对这里的速度慢做出一些有根据的猜测,并指出这将如何显示在分析器中

慢速getline()
getline()
可能以缓慢的方式实现。例如,它可能需要一次向运行时请求一个字符,因为一旦看起来是换行符,它就需要停止读取。也就是说,它不能在更大的块中请求字节,因为当块的中间出现换行符时,它不能保证“回退”其余块。

运行时几乎肯定会缓冲底层文件的读取,因此这不会像每个字符一次系统调用那么糟糕,但是为文件中的每个字符有效地调用
getc
的开销仍然很大

这将在探查器中显示为花费大量时间在
getline()
-中,特别是在getline调用的一些类似
getc()
-的方法中

python实现根本没有这个问题,因为只进行了一个
readlines()
调用,并且实现知道整个文件将被读取,并且可以随意缓冲

冗余复制 另一个可能的候选者是重复复制

第一次运行时调用
read()
并将文件块复制到内部缓冲区中。然后
getline()
实现可能会有一个内部缓冲区
    while (std::getline(infile, line)) {
        lines.push_back(std::move(line));
    }
std::string a("Hello");
std::string b(a);

std::cout<<a.size()<<" "<<b.size()<<std::endl;
std::cout<<"the address of a is : "<<a.c_str()<<" "<<b.c_str()<<std::endl;

std::string d(std::move(a));

std::cout<<a.size()<<" "<<d.size()<<std::endl;

std::string e;
std::string f;

e = b;

std::cout<<e.size()<<" "<<b.size()<<std::endl;
std::cout<<"the address of a is : "<<e.c_str()<<" "<<b.c_str()<<std::endl;


f = std::move(b);

std::cout<<f.size()<<" "<<b.size()<<std::endl;