posts - 7,  comments - 64,  trackbacks - 0

记得以前在一本书上看过boost::shared_ptr的回带来一定的效率损失,但是并不大.今天闲来无事,编译了一个BOOST并简单测试了一下,看看到底有多少性能损失.测试代码和结果如下:

比较函数
template <class T>
class compareP
{
public:
        bool operator() (const T lh,const T rh) const
        {
                return *lh<*rh;
        }

};


boost:
int _tmain(int argc, _TCHAR* argv[])
{
        DWORD oldtime = GetTickCount();
        typedef map<boost::shared_ptr<string>,size_t,compareP<boost::shared_ptr<string> > > container_type;
        typedef container_type::iterator iterator;
        container_type container;
        for (size_t i(0) ; i<500000 ; ++i)
        {
                boost::shared_ptr<string> pstr(new string);
                char buffer[32];
                *pstr = itoa(i,buffer,10);
                container[pstr]=0;
        }
        cout<<GetTickCount() - oldtime <<endl;
return EXIT_SUCCESS;
}

boost结果:
2000
2015
2015
2016
2017


指针:
int _tmain(int argc, _TCHAR* argv[])
{
        DWORD oldtime = GetTickCount();
        typedef map<string*,size_t,compareP<string*> > container_type;
        typedef container_type::iterator iterator;
        container_type container;
        for (size_t i(0) ; i<500000 ; ++i)
        {
                string *pstr = new string;
                char buffer[32];
                *pstr = itoa(i,buffer,10);
                container[pstr]=0;
        }
        cout<<GetTickCount() - oldtime <<endl;
return EXIT_SUCCESS;
}

指针结果:
937
938
954
953
953

执行速度已经相差一倍了.自动内存管理的代价啊!~~~~
环境:Q8200 2.33GHZ 4G内存

以上只是简单的测试,仅拱参考


补充说明:

很多朋友流言说在MAP中存放string*没有意义。可是我上一个项目就需要这么做。

试想我现在有10篇文档,现在需要统计每篇文档当中每个字出现的次数,还需要统计全部文章中全部字出现的次数。为了保证效率,应当保证每个字在内存当中只留一份拷贝(因为以后有可能统计每个词,甚至每句话出现的次数)。要实现这个功能,是否还有更好的算法?


还有朋友流言说指针版没有销毁string指针。可是在这个程序中执行cout<<GetTickCount() - oldtime <<endl;之前shared_ptr也没有释放资源。所以资源的释放不会造成误差。

luck朋友的方法最为有效,把比较函数变成:

bool operator() (const T &lh,const T &rh) const

        {

                return *lh<*rh;

        }

下面是shared_ptr执行5次的时间:

968

969

985

969

969


下面是string*执行5次的时间:

859

875

860

859

860


看来即使是小对象也不能放松!当很多小对象发生构造和析构时所耗费的时间还是不容小视的!~

posted on 2009-06-30 21:09 HIT@ME 阅读(3773) 评论(14)  编辑 收藏 引用

FeedBack:
# re: 关于boost库中shared_ptr执行速度的简单测试
2009-06-30 21:35 | skyscribe
你举的这个例子不具有典型性,实际中写出这样的代码,应该是需要再好好斟酌,谁会把shared_ptr作为map的索引呢?
应该举一个更切合实际的例子,譬如map的第二个字段是shared_ptr类型。
另外你的代码有没有把所有的优化都用上,强迫inline展开?  回复  更多评论
  
# re: 关于boost库中shared_ptr执行速度的简单测试
2009-06-30 23:31 | HIT@ME
我最近做的一个项目就需要把string*作为map的索引(比如统计文章中重复出现的单词数)。另外,是否强迫inline展开并不重要。因为主要说明shared_ptr确实对效率有影响,不是为了加快整个程序的执行效率。
明天我去公司再试试看把map换成vector,不过估计结果也差不多~@skyscribe
  回复  更多评论
  
# re: 关于boost库中shared_ptr执行速度的简单测试
2009-07-01 08:49 | 远古毛利人
楼主是否在Release下测试的?  回复  更多评论
  
# re: 关于boost库中shared_ptr执行速度的简单测试
2009-07-01 08:50 | Kevin Lynx
这个测试例子确实有问题。把一个对象(shared_ptr)和一个指针(string*)分别作为map的key,对象肯定会比指针慢。对象用于map的key会涉及到很多复制操作。  回复  更多评论
  
# re: 关于boost库中shared_ptr执行速度的简单测试
2009-07-01 09:10 | null
想不出来你为什么要用(string*)做key,既然用了指针,那肯定不是为了排序,如果是为了查找,那应该用hash_map(boost::unordered_map)  回复  更多评论
  
# re: 关于boost库中shared_ptr执行速度的简单测试
2009-07-01 09:29 | zuhd
用指针做key有什么意义呢?它和int做索引有什么区别?  回复  更多评论
  
# re: 关于boost库中shared_ptr执行速度的简单测试
2009-07-01 14:34 | test
主要是你的那个字符串太小了,相比较shared_ptr的构造计数等动作耗时差不多。所以才会差一倍。  回复  更多评论
  
# re: 关于boost库中shared_ptr执行速度的简单测试
2009-07-02 11:42 | luck
指针版的没有销毁string的指针  回复  更多评论
  
# re: 关于boost库中shared_ptr执行速度的简单测试
2009-07-02 17:52 | luck
把compareP类的操作符bool operator() (const T lh,const T rh) const
的参数改为引用传递就会减少很大部分的差别  回复  更多评论
  
# re: 关于boost库中shared_ptr执行速度的简单测试
2009-07-03 13:47 | 唐新发
下面的测试显示shared_ptr相对于使用原始指针会慢上很多(2-4倍),主要是来自引用计数及其带来的指针对象的创建销毁时间,下面的测试代码都是指针创建及传递操作:

#include <windows.h>
#include <cassert>
#include <iostream>
#include <string>
#include <boost/shared_ptr.hpp>

typedef int type;
typedef type* raw_ptr_type;
typedef boost::shared_ptr<type> shared_ptr_type;

template<typename T>
void use(T ptr)
{
T ptr1 = ptr;
T ptr2 = ptr;
T ptr3 = ptr;
}

int main(int argc, char* argv[])
{
size_t count = 500000;

if(argc > 1)
count = atoi(argv[1]);

DWORD oldtime, shared_ptr_time, raw_ptr_time;

{
oldtime = GetTickCount();
for (size_t i = 0; i < count ; ++i)
{
raw_ptr_type ptr(new type);
use(ptr);
delete ptr;
}
raw_ptr_time = GetTickCount() - oldtime;
}

{
oldtime = GetTickCount();
for (size_t i = 0; i < count ; ++i)
{
shared_ptr_type ptr(new type);
use(ptr);
}
shared_ptr_time = GetTickCount() - oldtime;
}

assert(raw_ptr_time <= shared_ptr_time);

std::cout << "count(" << count << ") raw_ptr(" << raw_ptr_time << " ms) shared_ptr(" << shared_ptr_time << " ms) diff(+" << shared_ptr_time - raw_ptr_time << " ms, +" << double(shared_ptr_time - raw_ptr_time)/double(raw_ptr_time)*100 << "%)"<< std::endl;

return EXIT_SUCCESS;
}

vc2008下 Release 禁用优化的三次执行:
count(500000) raw_ptr(110 ms) shared_ptr(591 ms) diff(+481 ms, +437.273%)
count(500000) raw_ptr(110 ms) shared_ptr(471 ms) diff(+361 ms, +328.182%)
count(500000) raw_ptr(120 ms) shared_ptr(471 ms) diff(+351 ms, +292.5%)

vc2008下 Release  完全优化的三次执行:
count(500000) raw_ptr(111 ms) shared_ptr(330 ms) diff(+219 ms, +197.297%)
count(500000) raw_ptr(100 ms) shared_ptr(331 ms) diff(+231 ms, +231%)
count(500000) raw_ptr(110 ms) shared_ptr(351 ms) diff(+241 ms, +219.091%)
  回复  更多评论
  
# re: 关于boost库中shared_ptr执行速度的简单测试
2009-07-04 16:28 | 99读书人网上书城
这个测试例子确实有问题  回复  更多评论
  
# re: 关于boost库中shared_ptr执行速度的简单测试
2009-07-05 22:50 | 李锦俊
堆中申请内存和销毁内存是极为耗时的。应该把测试做得更单纯一点才对。  回复  更多评论
  
# re: 关于boost库中shared_ptr执行速度的简单测试
2011-03-26 12:54 | 张立斌
for (size_t i(0) ; i<500000 ; ++i)
{
boost::shared_ptr<string> pstr(new string);
char buffer[32];
*pstr = itoa(i,buffer,10);
container[pstr]=0;
//shared_ptr在此处释放内存
}
for (size_t i(0) ; i<500000 ; ++i)
{
string *pstr = new string;
char buffer[32];
*pstr = itoa(i,buffer,10);
container[pstr]=0;
//内存泄露
}
如果不信,你可以把string改为自定义的类,并在构造和析构函数中加入输出。  回复  更多评论
  
# re: 关于boost库中shared_ptr执行速度的简单测试
2012-08-30 01:43 | qindh
我测试了share_ptr版式1847,new delete版是104,测试是用的VS2010版本,share_ptr不是用的boost库,是用的VS2010自带的  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2010年12月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

常用链接

留言簿(5)

随笔档案

test

搜索

  •  

最新评论

阅读排行榜

评论排行榜