我在我的代码中痴迷地使用向量、列表、字符串和 wstrings。是否有任何涉及到的 catch 22 让我对不时使用数组、chars 和 wchars 更感兴趣?
基本上,如果在支持标准模板库的环境中工作,是否有任何情况下使用原始类型实际上更好?
我会坚持使用 STL 类(向量、字符串等)。它们更安全、更易于使用、更高效,内存泄漏的可能性更小,而且,AFAIK,它们至少在调试时(Visual C++)对边界进行了一些额外的运行时检查。
然后,测量性能。如果您确定瓶颈在 STL 类上,则转到 C 样式字符串和数组的用法。
根据我的经验,在向量或字符串使用方面遇到瓶颈的机会非常低。
对于 99% 的时间和 99% 的标准库实现,您会发现 std::vectors 足够快,并且您从使用它们中获得的便利性和安全性将超过任何小的性能成本。
对于那些真正需要裸机代码的极少数情况,您可以将向量视为 C 样式数组:
vector <int> v( 100 );
int * p = &v[0];
p[3] = 42;
C++ 标准保证向量是连续分配的,因此保证可以工作。
关于字符串,便利因素几乎变得压倒性的,性能问题往往会消失。如果你回到 C 风格的字符串,你也会回到使用像 strlen() 这样的函数,这些函数本身就非常低效。
至于列表,在使用它们之前,您应该三思而后行,无论是您自己的实现还是标准。使用向量/数组可以更好地解决绝大多数计算问题。列表在文献中如此频繁出现的原因在很大程度上是因为它们是教科书和培训课程作者用来一次性解释指针和动态分配的一种方便的数据结构。我作为前培训课程作家在这里发言。
一个问题是访问元素时的开销。即使在通过索引访问元素时使用向量和字符串,您也需要首先检索缓冲区地址,然后添加偏移量(您不需要手动执行此操作,但编译器会发出此类代码)。使用原始数组,您已经有了缓冲区地址。在某些情况下,这种额外的间接性可能会导致大量开销,并且在您想要提高性能时会受到分析。
如果您不需要实时响应,请坚持使用您的方法。它们比字符更安全。
您偶尔会遇到这样的情况,您可以通过自己做一些事情来获得更好的性能或内存使用(例如,std::string 通常有大约 24 字节的开销,std::string 本身中的指针有 12 字节,以及其动态分配的块上的标题块)。
我从事从 std::string 转换为 const char* 的项目节省了显着的内存(10 的 MB)。我不相信这些项目是你所说的典型。
哦,使用 STL 会损害您的编译时间,在某些时候这可能是个问题。当您的项目导致将超过 GB 的目标文件传递给链接器时,您可能需要考虑其中有多少是模板膨胀。
我从事过几个项目,其中字符串的内存开销已经成为问题。
值得提前考虑您的应用程序需要如何扩展。如果您需要存储无限数量的字符串,将const char*
s 用于全局管理的字符串表可以为您节省大量内存。
但一般来说,除非有很好的理由不这样做,否则绝对要使用 STL 类型。
我相信默认的内存分配技术是向量的缓冲区,而字符串是每次当前分配的内存用完时分配双倍内存的技术。这可能很浪费。您当然可以提供自定义分配器...
要考虑的另一件事是堆栈与堆。静态大小的数组和字符串可以放在堆栈上,或者至少编译器会为您处理内存管理。如果较新的编译器提供相关的 C99/C++0x 功能,它们也会为您处理动态大小的数组。向量和字符串将始终使用堆,如果您有非常严格的约束,这可能会引入性能问题。
根据经验,使用已有的内容,除非它的速度/内存开销会损害您的项目……您可能会发现,对于 99% 的东西,STL 提供的类可以节省您的时间和精力,而对您的影响几乎没有影响应用性能。(即“避免过早优化”)