随心所“语”之 STL

    自己是个程序员,用C++开发也有5年时间了。期间,STL用的挺多了,对其印象也挺好的。

    网上、周围,许多人都不用STL,对此我比较疑惑。网上找了下,发现主要有下面几个问题:

1、代码膨胀。

     STL是模板实现,在每一个声明、使用的地方,都会扩展,导致代码膨胀。

     个人看法:的确存在这样一个问题,暂时也没看到好的解决。

2、不好用。

    STL的实现,主要是通用化了,所以许多开发中的个性化使用,会特别别扭。

    个人看法:的确,有的时候用STL,的确是觉得很别扭,因为代码来适配STL的容器、算法(当然,我也仅仅是使用,没有做深入的研究,也许我用法存在问题)。但是,既然标准化、通用化,必然会有这样的问题。我用c库的时候,有些也觉得别扭,要来适配它。这也是一样的道理。另外,可能是认识不够,用的不对也有可能。

3、效率不高

    STL实现会包很多层,操作效率低;还有人说,封装就引起了低效的可能。

    个人看法:首先,低效的说法,是经过测试了么?还是想象出来的?许多时候,想象出来的不一定是对的。其次,“封装引起可能低效”,我觉得过于追求效率了。如果是这样,为啥不直接用C、汇编呢?还搞什么的面向对象干啥呢?

4、跨平台问题(这个我看不懂,不好评价,把看到的copy。)

    二进制边界混乱。对需要在项目中使用第三方函数库的程序员来说,二进制边界是个头痛的问题。C++ 在这一方面本身就处理得不算好,加上模板后起到的是雪上加霜的后果。没有经验的程序员会贪图方便而在公开头文件中使用 C++ 模板,如果这时调用方的编译器选项设置或 STL 版本和编译方不同,那么就可能出现同样的头文件在不同的环境下二进制布局不符的情况。——顺便说一句,在过去十年里,各个主流编译器附带的 STL 版本变化节奏不慢,所以这种由于编译环境不同而导致的 bug 并不算罕见,但缺乏汇编知识的用户难以排查。

5、历史问题

    许多公司年代久远。STL刚出的时候,用过,发现不好用、有好多BUG,就不用了。然后,就有了这个规矩、编码规范。

    个人看法:我不知道STL以前怎么样,但是现在看来,还是不错的。

6、内存碎片问题

    STL小内存分配做的不是很好,导致内存碎片,会导致问题。

    个人看法网上有许多人是这个看法,但是,我认为大多数是“道听途说、人云亦云”,因为这么些个人中,许多人仅仅是说了这个结论,而没说原因;还有许多人认为STL是用new来分配内存的(STL是用malloc来分配的,可能老版本的STL是用new)。下面,我想来分析下“内存碎片”问题

    原因分析:

    STL本身内部有一个内存池。一般,内存池都是一个固定大小内存块用链表链起来;那么,把多个链表,就可以组成多个大小内存块的内存池。这就是STL的内存原理,它有8,16,32,64,128这几种大小的内存块组成的5个链表组成的内存池。

    内存分配的时候,大于128字节的内存,直接用malloc直接分配;128以内,内存池中取;如果刚开始内存池中没有内存块,那么会直接用malloc分配;当然,如果内存池中有,那么可以直接取,大内存块,可以重新划分为小块,给小块用。注意:STL的对象是分配内存、和调用构造函数分开的,分配内存用malloc,构造函数是用replace new。

    128以上的内存,直接用的malloc,那么跟其他的没有分别,所以,这个肯定不是STL的问题。128以下的内存,分配之后,是无法回收的——这个应该就是造成内存碎片的原因:那块小内存一直在那,无法回收,导致内存不连贯。

    但是,这种小内存真的会造成“内存碎片”导致内存不够吗?如果你的申请对象,主要是小对象的话,连续性申请,应该内存也是连续的;如果你的内存申请的大块的,那么就直接用malloc了,是可以回收的。当然,我没测试过内存碎片的问题(不知道怎么测试),我不知道STL的内存碎片问题到底会是什么样子的。

    另外,也许可以有改进的地方:stirng str('a',128);这样的对象定义1M个,那么就申请了1M个128的内存块放到内存池中,128的内存块,自动回分给其他的小内存用。所以,这种人为的预分配,那么,应该可以缓解这个问题。

    另外,tcmalloc安装之后,对STL有效吗?我觉得是有效的,因为STL用的是malloc。

     参考:为何某些公司不允许使用C++ STL


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值