【发布时间】:2018-09-22 06:51:44
【问题描述】:
如果数据结构(例如stack)已经在C++ STL中可用,我们需要自己定义和实现它们吗?
这两种实现有什么区别?
【问题讨论】:
-
这个问题太宽泛,无法回答,但你可能想看看这个关于为什么 FB 重新实现字符串的简短视频:youtube.com/watch?v=kPR8h4-qZdk
标签: c++ data-structures stl
如果数据结构(例如stack)已经在C++ STL中可用,我们需要自己定义和实现它们吗?
这两种实现有什么区别?
【问题讨论】:
标签: c++ data-structures stl
首先,自己实现一个现有的数据结构是一个有用的练习。您可以更好地理解它的作用(因此您可以更好地理解标准 containers 的作用)。特别是,您更了解为什么time complexity 如此重要。
然后,存在实施质量问题。标准实现可能不适合您。
让我举个例子。事实上,std::stack 正在实现一个堆栈。它是一个通用的实现。你测量过sizeof(std::stack<char>)吗?你有没有对它进行基准测试,平均有一百万个 3.2 个元素的堆栈,Poisson distribution?
也许在你的的情况下,你碰巧知道你有数百万的char-s 堆栈(从不NUL),其中 99% 有少于4个元素。有了这些额外的知识,您可能应该能够实现比标准 C++ 堆栈提供的“更好”的东西。所以std::stack<char> 会起作用,但考虑到额外的知识,您将能够以不同的方式实现它。你仍然(为了可读性和维护)会使用与std::stack<char> 相同的方法 - 所以你的WeirdSmallStackOfChar 将有一个push 方法等。如果(在项目后期)你意识到或者更大的堆栈可能有用(例如,在 1% 的情况下)您将以不同的方式重新实现您的堆栈(例如,如果您的代码库增长到一百万行 C++ 并且您意识到您通常有更大的堆栈,您可能会“删除" 你的 WeirdSmallStackOfChar 类并添加 typedef std::stack<char> WeirdSmallStackOfChar; ....)
如果您碰巧知道所有您的堆栈少于 4 个 char-s 并且 \0 在其中无效,则将此类“堆栈”-s 表示为 @987654340 @field 可能是最明智的方法。它快速且易于编码。
因此,如果性能和内存空间很重要,您可能会编写一些像
这样奇怪的代码class MyWeirdStackOfChars {
bool small;
union {
std::stack<char>* bigstack;
char smallstack[4];
}
当然,这是非常不完整的。当small 为真时,您的实现使用smallstack。对于 1% 错误的情况,您的实现使用bigstack。 MyWeirdStackOfChars 的其余部分留给读者作为练习(不是那么容易)。别忘了关注rule of five。
好吧,也许上面的例子没有说服力。但是std::map<int,double> 呢?您可能有数百万个,并且您可能知道其中 99.5% 小于 5。您显然可以针对这种情况进行优化。很有可能,通过成对的 int 和 double 数组来表示小地图在内存和 CPU 时间方面都更有效。
有时,您甚至知道所有您的地图的条目少于 16 个(std::map<int,double> 不知道这一点)并且键是从不 0。那么你可能会以不同的方式表示它们。在那种情况下,我想我能够实现比std::map<int,double> 提供的更有效的东西(可能是因为cache 效果,一个包含int 和double 的16 个条目的数组是最快的)。
这就是为什么任何开发人员都应该了解经典算法(并阅读过一些Introduction to Algorithms)的原因,即使在许多情况下他会使用现有的容器。还要注意as-if rule。
【讨论】:
对于所有可能的用例,数据结构的 STL 实现并不完美。
我喜欢哈希表的例子。我使用 STL 实现已经有一段时间了,但我主要将它用于竞争性编程竞赛。
假设您是 Google,并且您拥有 数十亿美元的用于存储和访问哈希表的资源。您可能希望为公司用例提供可能的最佳实施,因为它通常会节省资源并加快搜索速度。 哦,我忘了提到你还有一些地球上最好的工程师为你工作(:
(此视频由 Kulukundis 制作,讲述他在 Google 的团队制作的新哈希表) https://www.youtube.com/watch?v=ncHmEUmJZf4
有理由实施您的自己的版本数据结构的其他一些原因:
测试您对特定结构的理解。
自定义部分结构 结构的某些特殊用例。
为特定的数据结构寻求比 STL 更好的性能。
讨厌 STL 错误。
基准测试针对一些简单实现的 STL。
【讨论】: