考虑到插入顺序与搜索速度同样重要,20 个条目的 STL 列表或 STL Map 哪个更好

发布于 2024-08-28 21:25:07 字数 317 浏览 5 评论 0原文

我有以下场景。实时应用程序需要实现。

1)我需要在容器中存储最多 20 个条目(STL Map、STL List 等)。 2)如果有新条目出现并且已经存在 20 个条目,我必须用新条目覆盖最旧的条目。

考虑到第 2 点,我觉得如果容器已满(最多 20 个条目),“列表”是最好的选择,因为我始终可以删除列表中的第一个条目并最后添加新条目(push_back)。但是,搜索不会那么有效。

只有20条条目,如果我用列表代替地图,搜索效率真的有很大区别吗?

还考虑到在地图中插入的成本,我觉得我应该选择一个列表?

您能告诉我什么是更好的选择吗?

I have the following scenario.The implementation is required for a real time application.

1)I need to store at max 20 entries in a container(STL Map, STL List etc).
2)If a new entry comes and 20 entries are already present i have to overwrite the oldest entry with the new entry.

Considering point 2, i feel if the container is full (Max 20 entries) 'list' is the best bet as i can always remove the first entry in the list and add the new one at last (push_back). However, search won't be as efficient.

For only 20 entries, does it really make a big difference in terms of searching efficiency if i use a list in place of a map?

Also considering the cost of insertion in map i feel i should go for a list?

Could you please tell what is a better bet for me ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

瑾兮 2024-09-04 21:25:08

1)我需要在容器中存储最多 20 个条目(STL Map、STL List 等)。 2)如果有新条目出现并且已经存在 20 个条目,我必须用新条目覆盖最旧的条目。

在我看来,这似乎是 boost::circular_buffer< 的工作/a>.

一般来说,术语循环缓冲区是指内存中用于存储传入数据的区域。 当缓冲区填满时,新数据将从缓冲区的开头开始写入并覆盖旧数据

circular_buffer 是一个符合 STL 的容器。它是一种类似于 std::list 或 std::deque 的序列。它支持随机访问迭代器、在缓冲区开头或结尾的恒定时间插入和擦除操作以及与 std 算法的互操作性。 circular_buffer 专门设计用于提供固定容量存储。当其容量耗尽时,新插入的元素将导致缓冲区开头或结尾的元素(取决于使用的插入操作)被覆盖

circular_buffer 仅在创建时分配内存、显式调整容量或根据需要适应大小调整或分配操作。另一方面,还有一个circular_buffer_space_optimized可用。它是circular_buffer的适配器,在创建时不会立即分配内存,而是根据需要分配内存。

对于快速搜索,我认为只有 20 个元素(如果它们的比较不是太复杂)就可以使用像这样的“低成本”容器和普通的线性搜索,在我看来,这将很难实现与其他 STL 容器相比具有更好的性能。

1)I need to store at max 20 entries in a container(STL Map, STL List etc). 2)If a new entry comes and 20 entries are already present i have to overwrite the oldest entry with the new entry.

This seems to me the job for boost::circular_buffer.

In general the term circular buffer refers to an area in memory which is used to store incoming data. When the buffer is filled, new data is written starting at the beginning of the buffer and overwriting the old.

The circular_buffer is a STL compliant container. It is a kind of sequence similar to std::list or std::deque. It supports random access iterators, constant time insert and erase operations at the beginning or the end of the buffer and interoperability with std algorithms. The circular_buffer is especially designed to provide fixed capacity storage. When its capacity is exhausted, newly inserted elements will cause elements either at the beginning or end of the buffer (depending on what insert operation is used) to be overwritten.

The circular_buffer only allocates memory when created, when the capacity is adjusted explicitly, or as necessary to accommodate resizing or assign operations. On the other hand, there is also a circular_buffer_space_optimized available. It is an adaptor of the circular_buffer which does not allocate memory at once when created, rather it allocates memory as needed.

For the fast search, I think that with just 20 elements (if their comparison isn't too complicated) you're ok with a "low-cost" container like this and normal linear search, in my opinion it would be difficult to achieve better performance with other STL containers.

浅唱ヾ落雨殇 2024-09-04 21:25:08

保持插入顺序,或允许快速搜索:选择其中之一。

std::map 在这里不是一个选项,因为它不维护插入顺序。此外,它是一个关联容器。您应该在 listdequevector 之间进行选择。就性能而言,您最好的选择是列表,因为您可以从后面弹出一个元素并在前面插入一个新元素(反之亦然),而不会造成任何移位或性能损失。

顺便说一句,在 map 中插入的成本并不昂贵:大约为 O(log n)。对于 20 个元素来说几乎不相关。这同样适用于 std::set

Maintain order of insertion, or allow fast searching: choose one.

std::map is not an option here because it doesn't maintain the order of insertion. Besides, it's an associative container. You should choose between a list, a deque and a vector. In terms of performance your best bet is a list, since you can pop off an element from the back and insert a new one at the front (or vice-versa) without any shifting or performance penalty.

The cost of insertion in a map, just as a sidenote, isn't expensive it all: it's in the order of O(log n). Practically irrelevant in the case of 20 elements. The same holds for a std::set.

初雪 2024-09-04 21:25:08

由于只有 20 个元素,我不会太担心您使用哪个容器。如果您确定所选的容器实际上会损害应用程序的性能,那么稍后更换所选的容器并用更高效的容器替换它应该相对容易。

话虽如此,对于大量元素, std::deque 可能会为您想要完成的任务提供最佳的全面效率。与 std::vector 不同,std::deque 允许从前面删除,而无需移动所有其他元素。与 std::list 不同,std::deque 允许随机访问其元素。

With only 20 elements, I would not worry much about which container you use. If you determine that the container chosen is in fact a detriment to the performance of your application, it should be relatively easy to swap out the container chosen and replace it with a more-efficient container later.

With that being said, for a large number of elements, the std::deque would probably give you the best all-around efficiency for what you are trying to accomplish. Unlike std::vector, std::deque allows for removal from the front without needing to move all of the other elements. Unlike std::list, std::deque allows for random access of its elements.

一绘本一梦想 2024-09-04 21:25:08

您只需要实现一个优先级队列。 STL 地图不起作用。

You just need to implement a priority queue. STL Map doesn't work.

渔村楼浪 2024-09-04 21:25:08

这取决于元素的大小。

根据我自己的经验,我知道对于五个整数,使用线性搜索搜索的无序整数数组更快比有序集合、列表插入排序和二分搜索更快。大批。

无序数组的 O() 表示法可能比任何其他选项都要差得多,但 O(N+C) + C 中通常看不见的 C 却要小得多。

列表、集合或映射(任何使用动态内存并通过指针链接的东西)将主要受到缓存未命中、内存分配和间接引用惩罚的影响。

It depends on the size of the elements.

I know from my own experience that for five integers an unordered array of integers searched with linear search is faster than a set, a list or insertion sort and binary search on an ordered array.

The O() notation of an unordered array may be much worse than any of the other options but the normally unseen C in O(N+C) + C is so much smaller.

A list, set or map (anything that uses dynamic memory and is linked by pointers) will be dominated by cache misses, memory allocations and indirect reference penalties.

深海夜未眠 2024-09-04 21:25:08

您需要在阵列上实现优先级队列。
有关实现,请参阅二进制堆

You need a Priority Queue implemented on an array.
See the Binary Heap for an implementation.

难得心□动 2024-09-04 21:25:08

您已经知道这是一个瓶颈吗?

我的建议是首先使用在编程时更容易阅读的内容,并且仅在发现性能不是您需要的时候才优化它。

Do you already know that this is a bottleneck?

My advice would be to first use what is more natural to read while programming and only optimize it when you see that the performance is not what you need.

烂人 2024-09-04 21:25:08

我的建议是制作一个循环缓冲区。但只有当“旧”是由插入时间决定的,而不是某个字段时,这才有效。

如果您需要一个合适的 LRU,那么您可能应该去看看类似 http://www.codeproject.com/KB/recipes/LRUCache.aspx?fid=1000025&df =90&mpp=25&noise=3&sort=Position&view=Quick&fr=15

但是,如果您的最大值为 20 个条目,您将很难找到实际上更快的复杂算法而不是对每个元素进行简单的线性检查。

My suggestion would be to make a circular buffer. But that only works if "old" is determined by when it was inserted, and not some field.

If you need to have a proper LRU, then you should probably go and look at something like http://www.codeproject.com/KB/recipes/LRUCache.aspx?fid=1000025&df=90&mpp=25&noise=3&sort=Position&view=Quick&fr=15

But with 20 entries as your max, it will be very hard to you to find a complex algorithm that is actually faster than the trivial lineary check of every element.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文