1、stl内存池有很多种实现,目标是尽量优化小对象的内存分配;你的数据显然没有真正反映gcc的内部实现,建议自己看看源码。 2、请注意,string是一个typedef;它是basic_string的一个特化版。 basic_string的最后一个模板化参数用于指定内存池;默认内存池一般是全局公用的。 另外,不仅是basic_string,凡声称自己可以支持多线程的stl组件,都会通过traits(似乎是这个词儿)自动在多线程环境下加入锁保护——当然,你也可以手工去掉它。 具体实现各家皆有细微差别,看源码即知。 3、关于性能,论坛上颇有一番“一群阔人说要读经,嗡的一声一群狭人也说要读经”的气象。 先反问一下:知道“锁操作慢”是搞什么的人才有资格说的吗? ——对那美克星的亚光速飞船来说,F22比猎豹眼里植物生长的速度还慢。 看下数据(原始数据来自IBM;是在下为写另一帖子找的,现在原文不在,就暂时不给链接了): 对PIII 700来说,这款CPU每时钟周期可以执行两条整数指令,它的时钟周期是1.4ns。 这款CPU有两种原子操作指令,消耗时间分别是7xns和14xns的样子(具体数字忘了)。 作为对比,一旦此CPU要访问的数据不在cache中,那么哪怕只从内存中读取一个字节,也需要100多ns。 换言之: 一次原子操作,需要消耗的时间基本和一次cpu二级缓存未命中相当。 再做个对比:现在最好的磁盘,平均寻道时间大约是9ms不到,仅仅是在两个相邻磁道间移动磁头就需要消耗2ms;然后,它还需要等待对应扇区转到磁头下——对于10000转的硬盘,这个时间(平均等待时间)是3ms。 加上其他种种延迟,缓存未命中时,从磁盘读取一个字节平均需要至少21ms。 这段时间,足够老掉牙的PIII 700执行30万条原子指令(或3000万条整数指令)。 进一步的,锁的实现可分为两种: 一种是简单调用原子操作指令实现基本逻辑,由用户负责调度算法;另一种则还要通知操作系统内核,以将合适的进/线程挂起或恢复执行。 于是,一个锁操作,全部消耗可能是一次函数调用(可以被inline优化掉)+一个原子指令;也可能是一次用户态-内核态-用户态切换+若干次函数调用+一个原子操作。 这点开销,与一个本该inline而没有inline的函数所造成额外消耗基本在同一个数量级上。 总结: 1、锁速度慢是那些有能力玩优化玩到单条机器指令级的算法大佬们才有资格说的(或者说:只有当你可以准确估算出自己的代码将消耗多少个指令周期、有多少次CPU二级缓存未命中时,谈论锁对性能的影响才有意义——这时候,你也往往必须自己用CPU原始原子操作指令完成保护以提高性能了)。 2、对普通用户来说,请记住这句话:“和普通函数调用相比,锁操作基本没有额外消耗”。 3、论坛上那些不分情况不看场合张嘴就是“锁很慢”“xxx操作效率低”的牛人,他们其实对速度、性能、效率等等几乎毫无概念,只是人云亦云而已。切莫被他们误了。 |