读书人

只看到STL的好处等于不懂STL,该如何处

发布时间: 2012-02-24 16:30:39 作者: rapoo

只看到STL的好处等于不懂STL
这几天写了一些东西,从而也就有感而发STL的些许不足。 现在这个社会,一个比较好的东西出来之后,一大摞一大摞的书籍就出来,大吹这些东西的优点:怎么怎么好用,怎么怎么高效,怎么怎么节约开发时间等等。 但是惟其缺点闭口不提;就算一些大师级人物也不过如此; 如果要我举个例子的话,台湾的李维可算是一个,从一个大师级人物变成一个吹鼓手实在令人费解。

这两天自己写了个HashDictionary,同时支持GetIdByWord和GetWordById, Insert.开发的演变过程如下: 1使用线性探测来解决冲突,基于线性探测的天生缺点,譬如很难支持删除和容易扎堆等,效果显然不好。 2 用vector , 我一个80M的文件竟然吃了我差不多800M的内存,效果实在垃圾。事实上,PJ实现的hashmap和hashset使用的是vector,和这里vector也差不多,都是在每个桶挂一个双向链表 3自己写个单向链表的结构,替换list;但还是每次都用缺省的new来分配内存,内存使用少了一些,但还有400M左右,很难差强人意。 怪就要怪缺省的new。 使用这个new,如果你发现一个80M的东西漏进内存之后可能会占用400M的内存,请不要惊讶。因为每个new都会额外占用24个字节的空间,应该是用来管理内存碎片和相邻的空闲内存(这点具体不是很清楚);而且每次分配都是基于8个字节来分配的,也就是说,如果你new char[1]的话,实际上是占用了24 + 8 = 32个字节。 new char[8]也是32个, new char[9] 则占用24 + 16 = 40个字节。 4 自己做内存池,自己分配自己管理,一个程序从头到尾就使用了几次new;这里浪费的24个字节几乎完全干掉。还是80M的文件,就只占用140M内存左右,而且负载系数是60%; 如果还想进一步减少空间,用时间来换取空间,可以做到100M。 这才是我想要的。至于具体的实现,我这份不能给你,因为我们写的代码不公开;sgi有一份,但每个应用都可以对它进行优化。但是在这些方面(也包括处理Unicode等问题),如果有问题,我会尽力讨论。 前段时间针对Unicode读写文件,也遇到同样的问题,stl的wiostream, wiostringstream等就不能直接的解决问题,还得自己写个CIOUnicode。

STL还有很多需要每个使用者去认识的地方,因为通用的东西本来就很难做到最好,我也期待vc2005和新的C++/CLI。 发句感叹: 只看到STL的好处等于不懂STL。

[解决办法]
因为你的程序有很强的数据针对性以及内存管理的片面性,所以这样,STL之伟大在于its flexibility 当然没有东西是完美的~
[解决办法]
楼主强人,不过vc2005早就出了,楼主莫不是转贴?
[解决办法]
STL里面很多东西都可以定制的啊,vector可以定制自己的allocator,wofstream可以利用imbue自己写得一个codecvt来读写unicode文件,......
STL需要理解才能使用得高效。
也不能指望vc2005能做得有多完美,通用的东西总是比不上专门的处理,幸好的是,在STL里,基本上一些关键的部位,都可以使用自己写的东西。

[解决办法]
看了一下 VS2005,其中默认的allocator仍然是直接new和delete的,没有象SGI那样做优化。
所以,对于内存密集型程序,还是自己写allocator比较好。

但是我要说vector本身是不会因为大量new而占用内存的,因为它是连续的一块内存,不管曾经new了多少次,当前有效的只有一次new,因此也只有一次消耗。所以它时间上是低效的,但空间上不是。(至少C++标准是这样要求的,VS2005 中也是这么实现的。如果LZ的编译器不是,那么它一定不完全支持标准。如VC6使用的是94年的PJ版本,当时标准还没有成形,特别是关于STL的部分)。而hash_map,list等确实需要每次调用allocator分配节点内存,这种情况下,还是为它们重写allocator吧。
为::new、::delete写内存池我也做过,但是也不是很省空间,至少每次分配要损失4字节存储长度。所以还是写allocator比较好,它在释放时能够告诉你长度, 这部分被节省的空间对小对象而言还是很可观的。

另外wiostream, wiostringstream等属于标准库,但是不属于STL,虽然它们也都是用模版来定义的。Unicode没接触过,不便妄论。我只知道用wiostream要用对应的wchar_t , wstring等。并且unicode与ascii之间的转换语言本身是不提供的。编译器往往自行扩充,如VS2005提供了mbstowcs/wcstombs 完成这些转换。

读书人网 >C++

热点推荐