简体   繁体   English

FIFO std::queue<std::string> 过度复制大字符串?

[英]Does a FIFO std::queue<std::string> excessively copy large strings?

I'm implementing a simple producer thread and consumer thread that uses a shared std::queue<std::string> to pass very long strings from the producer to the consumer, locking a mutex while the queue is added to/removed from.我正在实现一个简单的生产者线程和消费者线程,它使用共享的std::queue<std::string>将很长的字符串从生产者传递给消费者,在添加/删除队列时锁定互斥锁。

My main uncertainty is that I'm not sure how queue is managing the strings.我的主要不确定性是我不确定队列是如何管理字符串的。 Aside from when the initial insertion to the queue happens, are the entire strings being copied around during their lifetime in the queue?除了最初插入队列的时间之外,是否整个字符串在队列中的生命周期中都被复制?

The short answer is no.最简洁的答案是不。 Unless you use quite an old compiler, they probably won't be copied at all while they're in the queue.除非您使用相当老的编译器,否则它们在队列中时可能根本不会被复制。

By default, std::queue uses an std::deque for its underlying storage.默认情况下, std::queue使用std::deque作为其底层存储。 Unlike (for example) an std::vector , an std::deque doesn't usually use contiguous storage.与(例如) std::vectorstd::deque通常不使用连续存储。 Instead, its a vector of pointers, where each of those pointers refers to a fixed-size block of items being stored.相反,它是一个指针向量,其中每个指针都指向一个固定大小的存储项目块。 When you add items to the deque, it doesn't copy those blocks containing the actual items at all.当您向双端队列添加项目时,它根本不会复制包含实际项目的那些块。 Instead, it just allocates another fixed-size block, and adds its address to the vector of pointers.相反,它只是分配另一个固定大小的块,并将其地址添加到指针向量中。

As a result, at least in the usual implementation of a deque (and therefore queue , at least by default) an item remains in exactly the same location in memory from the time it's pushed until the time it's popped.因此,至少在deque的通常实现中(因此queue ,至少在默认情况下)一个项目从它被推送到它被弹出的时间保持在内存中完全相同的位置。

But also note that even if you stored the items in something like a vector that can move items from one block of memory to another, it wouldn't normally cause a problem except (possibly) on quite an old compiler (pre C++-11).但还要注意,即使您将项目存储在可以将项目从一个内存块移动到另一个内存块的vector中,它通常也不会导致问题,除非(可能)在相当旧的编译器(C++-11 之前)上. Starting with C++11, items can be moved rather than copied.从 C++11 开始,可以移动而不是复制项目。 When you move a long string, you'll copy copy a few bookkeeping items (pointer to the data, current size allocated, current size in use), but the actual data for the long string will not be copied.当您移动一个长字符串时,您将复制一些簿记项(指向数据的指针、当前分配的大小、当前使用的大小),但不会复制长字符串的实际数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM