Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.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++ STL内部问题_C++_Optimization_Stl_Io_Mmap - Fatal编程技术网

C++ STL内部问题

C++ STL内部问题,c++,optimization,stl,io,mmap,C++,Optimization,Stl,Io,Mmap,我目前正在写一些关于二进制数据IO的摘要。在这一点上,我目前不确定STL在这些任务中的表现如何。例如,我有很多东西可以将二进制编码为char*或std::vector。现在,每当我有一个这种字节类型的对象时,我要么使用ostream::write()编写它,要么对数组执行std::copy,将其复制到流中的ostream_迭代器。现在我想知道,拷贝在内部会做什么 据我所知,STL可以优化任何东西。例如,理论上,使用std::copy存储字符的两个向量的副本不应缓慢地逐字节复制这些字符,而应使用系

我目前正在写一些关于二进制数据IO的摘要。在这一点上,我目前不确定STL在这些任务中的表现如何。例如,我有很多东西可以将二进制编码为char*或std::vector。现在,每当我有一个这种字节类型的对象时,我要么使用ostream::write()编写它,要么对数组执行std::copy,将其复制到流中的ostream_迭代器。现在我想知道,拷贝在内部会做什么

据我所知,STL可以优化任何东西。例如,理论上,使用std::copy存储字符的两个向量的副本不应缓慢地逐字节复制这些字符,而应使用系统原语来复制数据块(如果可用)。这是如何在内部完成的

我问这个问题的原因是,我现在正试图将文件切换到mmaped内存,而不是std::ostreams。这意味着,写入char*数据将非常简单,但写入向量将是逐字节的。我必须在我的课堂上为STL提供什么来优化复制(可能使用memcpy)?我想我需要合适的迭代器,但是它们需要什么,这样STL就会知道它可以只进行memcopy而不是遍历它们


我知道这要求很多我通常不应该关心的东西(封装原则通常是一件很棒的事情)。当然,我知道Knuths优化规则,这就是为什么我关心STL的自动优化功能。

如果您不确定STL的性能如何,那么测试是无法替代的。时间多次复制一块数据需要多长时间,使用memcopy复制相同数量的数据需要多长时间,并进行比较


亲自进行这些测试远比担心STL优化更有意义。

iostream
仅用于格式化(即文本)IO。如果需要二进制IO,则必须使用
streambuf

此外,iostreams以速度慢著称(由于各种原因,您的里程数也会有所不同)

Iostreams在内部使用streambuf,它添加了一层间接寻址,并为您提供自动缓冲。如果您需要合理的二进制IO吞吐量,您可能希望直接使用streambuf派生类(如
fstreambuf
)并对其进行基准测试(并禁用)

或者您可以直接使用
mmap
write
。这些函数使用起来非常简单,围绕它编写自己的类应该很容易


哦,不要对标准库的功能做任何假设。如果你想更多地了解它是如何在内部工作的,请查看GNU实现的来源。

你问的并不清楚。您提到了向量、
std::copy
char*
和内存映射文件,但它们之间没有明显的联系。向我们展示一些代码,或者描述您正在尝试做什么,以及使用什么样的数据类型

但STL实现中的一个常见优化是使用
memcpy
或类似的原始内存复制机制,只要复制的对象类型是POD。因此,假设STL实现中存在这种优化,您所要做的就是确保要复制的对象是POD类型


但正如前面提到的,获得可靠的性能信息的唯一方法是自己对其进行分析/测量/基准测试。

就像你说的,我们不知道。迭代器只在其中存储一个指针,因此编译器可以很好地优化副本。你必须尝试一下,看看它是否适合你和你的编译器。为什么要逐字节复制向量?我真的看不到与
std::copy
的连接。您可以在字符数组和向量上使用
std::copy
。除了“自己测量”的明显建议外,还向我们展示一些代码。我们不知道你的向量中有什么,也不知道它是如何被复制的,所以告诉你它被复制的速度是不可能的。我认为向量将以逐字节的方式被复制的原因是,因为我需要将std::copy算法一个自定义迭代器传递到mmaped内存区域。从这个迭代器,STL将不得不推断出它可以从参考实现中优化循环。但是它在这个推断中使用了什么信息?我如何提供它?这个“自定义迭代器”可能只是一个
char*
,对吗?如果您的STL实现(请,而不是“STL”)有专门用于复制到
char*
,那么这些显然适用。(你也可以自己专门化
std::copy
,只要你遵循一个定义规则。)@Christopher Yeah,几分钟前我自己就意识到了这一点,如果我在缓冲区类中只做一个
typedef char*迭代器,我的生活会简化很多。另外,还感谢您提供了关于专门化
std::copy
的提示。好的,对streambuf的提示似乎非常有用。但是,我在我的网站上找不到fstreambuf的参考。你有没有链接到某个地方,我可以在那里获得更多信息?吹毛求疵:测试只能向你展示STL的实现与你拥有的编译器的性能,并且这些参数可以随着下一次编译器升级而改变。您自己的代码的优化也是如此。除此之外,我同意你说的。非常正确。当然,这加强了这一点;测试将是确定编译器升级如何影响性能的唯一方法。我认为OP可能在寻找一个简单的“STL(对于您的任务来说太慢了|足够快了)”,而除了“测试它”之外的任何答案都可能因编译器或STL更改而无效。