Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.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++;字符串连接的开销_C++_String_Optimization_File Io - Fatal编程技术网

C++ c++;字符串连接的开销

C++ c++;字符串连接的开销,c++,string,optimization,file-io,C++,String,Optimization,File Io,我正在从ifstream读取一个随机ascii文本文件。我需要能够将整个消息放入字符串类型中进行字符解析。我目前的解决方案是可行的,但我认为我使用了与此等效的方法,在更冗长的文件上浪费了处理时间: std::string result; for (std::string line; std::getline(std::cin, line); ) { result += line; } 我担心这样连接字符串的开销(这种情况发生了几千次,消息长度为10个字符)。在过去的几天里,我浏览了各

我正在从ifstream读取一个随机ascii文本文件。我需要能够将整个消息放入字符串类型中进行字符解析。我目前的解决方案是可行的,但我认为我使用了与此等效的方法,在更冗长的文件上浪费了处理时间:

std::string result;

for (std::string line; std::getline(std::cin, line); )
{
    result += line;
}
我担心这样连接字符串的开销(这种情况发生了几千次,消息长度为10个字符)。在过去的几天里,我浏览了各种可能的解决方案,但没有什么是非常合适的。。。我事先不知道消息的长度,所以我不认为使用动态大小的字符数组是我的答案

我读了一遍,听上去几乎适用,但仍然让我不确定


有什么建议吗?

如果您知道文件大小,请使用result的成员函数'reserve()'一次。

我太困了,无法为您整理任何可靠的数据,但最终,如果事先不知道文件大小,您将不得不这样做。事实上,您的标准库实现足够智能,可以相当智能地处理字符串大小调整。(尽管事实上,
std::string
没有指数增长保证,就像
std::vector
那样)

因此,尽管在前50次迭代中可能会看到不必要的重新分配,但过了一段时间,重新分配的块变得非常大,以至于重新分配变得非常罕见


如果您分析并发现这仍然是一个瓶颈,那么可以使用
std::string::reserve
自己创建一个典型数量。

您正在为文件中的每一行复制结果数组(在展开结果时)。而是预分配结果并使其按指数增长:

std::string result;
result.reserve(1024); // pre-allocate a typical size

for (std::string line; std::getline(std::cin, line); )
{
    // every time we run out of space, double the available space
    while(result.capacity() < result.length() + line.length())
        result.reserve(result.capacity() * 2);

    result += line;
}
std::字符串结果;
结果.保留(1024);//预先分配一个典型尺寸
for(std::string-line;std::getline(std::cin,line);)
{
//每次空间用完时,可用空间就会加倍
而(result.capacity()
问题在于您无法提前知道完整大小,因此无法适当分配内存。我希望您得到的性能影响与此相关,而不是与
string
s的连接方式相关,因为它是在标准库中高效完成的

因此,我建议推迟连接,直到您知道最终
字符串的完整大小。也就是说,首先将所有字符串存储在一个大的
向量中,如下所示:

使用名称空间std;
矢量全谱线;
大小\u t总大小=0;
//如果您可以访问所需数据的总大小
//要读取(输入文件的大小,…),只需初始化totalSize
//并且只使用下面的第二个代码段。
for(字符串行;getline(cin,line);)
{
所有线路。向后推(线路);
totalSize+=line.size();
}
然后,您可以创建大的
字符串
,事先知道其大小:

string finalString;
最终储备(总规模);
for(vector::iterator itS=allLines.begin();itS!=allLines.end();++itS)
{
finalString+=*itS;
}

尽管如此,我还是要指出,只有在遇到性能问题时,才应该这样做。不要试图优化那些不需要优化的东西,否则你会使你的程序复杂化,而没有明显的好处。我们需要优化的地方通常是违反直觉的,并且可能因环境而异。所以,只有当你的分析工具告诉你需要的时候,你才能这样做。

这真的是一个问题吗?你可以用它一次构造字符串。@MFONTANI:不,他只是为了好玩才编造出来的。和你我一样,他没有更好的时间,如果流意味着一个文件,一个文件意味着你可以统计,你可以统计意味着你知道它的大小;我遗漏了什么吗?好吧,如果他不知道大小并且不想连接,为什么不简单地逐行解析呢?并不是说串联是一个值得关注的问题。与其冒着每次串联都可能重新分配的风险,不如收集链表中的子串并在最后将它们全部串联起来?尽管您在每个子字符串上调用
new
,但这种解决方案可能不会比std::string的重新分配更为有效,因为重新分配std::string的频率较低,但成本较高;绳子可能有道理,但我严重怀疑性能问题是由于内存分配造成的…@AlexChamberlain:好的,后续副本对于复杂性没有帮助-引用字符串构造函数取值范围具有线性复杂性,但我看不到标准中的确认(尽管它提供了向量)。有趣的是,这是CPPPreference的bug吗?@LightnessRacesinOrbit,嗯,我看到这行:)它不是它看起来的样子-X(t,m)。m是分配器,不是迭代器。什么样的文件你不能得到字节长度?正如你在OP问题中看到的,他在这里使用
cin
,这是一个例子。此外,您还可以逐个访问接收到的网络资源,依此类推。(等等)@Mic:你忘了读第一行了吗
我正在从ifstream读取一个随机ascii文本文件。
但是仍然存在约束的有效原因。老实说,我认为ddriver是相当短视的。@ddriver:
/dev/random
是一个文件,但它的字节大小是多少?这里的亮度是正确的,我的停止点确实是未知的。我根据在读入期间从流中收集的信息停止(我是在“实时”解密这些字符的一小部分,长话短说!)。因此,简单地将存储空间==设置为文件大小是浪费的。我读过很多书