免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5256 | 回复: 11
打印 上一主题 下一主题

请教为什么std::map erase() hpux与linux性能差距巨大? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-05-09 10:58 |只看该作者 |倒序浏览
大家好:

同样一段代码在HPUX上比linux删除操作慢了20多倍,如果map的key换成int,那么性能差不多,请问是什么原因导致的,谢谢。HpUx上的代码使用aCC编译。插入操作性能差不多。

#include <string>
#include <map>
#include <vector>
#include <sys/time.h>
#include <stdio.h>

static struct timeval tm_begin, tm_end;

#define BEGIN_CALC_TIME gettimeofday (&tm_begin, NULL)
#define END_CALC_TIME gettimeofday (&tm_end, NULL)

#define SHOW_TIME \
do {\
        printf ("time: %lu\n", 1000000 * (tm_end.tv_sec - tm_begin.tv_sec) + (tm_end.tv_usec - tm_begin.tv_usec)); \
} while (0)


int
main ()
{
        std::map<std::string, int> mapA;
        std::vector<std::string> vecA;
        char key[16];

BEGIN_CALC_TIME;
        for (int i = 0; i < 1000000; ++i) {
                snprintf (key, 16, "key%d", i);
                mapA.insert (std::make_pair (std::string (key), i));
                vecA.push_back (std::string (key));
        }
END_CALC_TIME;
SHOW_TIME;
        printf ("size: %d\n", mapA.size ());

        std::vector<std::string>::iterator iter = vecA.begin ();
        std::vector<std::string>::iterator iter_end = vecA.end ();
BEGIN_CALC_TIME;
        for (; iter != iter_end; ++iter) {
                mapA.erase (*iter);
        }
END_CALC_TIME;
SHOW_TIME;

        printf ("size: %d\n", mapA.size ());
}

论坛徽章:
0
2 [报告]
发表于 2012-05-09 11:01 |只看该作者
用int效率差不多,说明问题不在map.
你用string做key, 可能效率差在string的实现上.

论坛徽章:
0
3 [报告]
发表于 2012-05-09 11:45 |只看该作者
回复 2# hgrany

谢谢。我也觉得不是红黑树实现的问题,我还有一个测试程序,使用字符串作为key,性能也是差距巨大,最少十倍,开始怀疑是strcmp两个平台性能差距大,经过测试HP上要比linux还稍微快点。

#include <map>
#include <vector>
#include <list>
#include <stdio.h>
#include <string>
#include <string.h>

#include <sys/time.h>
#include <stdio.h>

static struct timeval tm_begin, tm_end;

#define BEGIN_CALC_TIME gettimeofday (&tm_begin, NULL)
#define END_CALC_TIME gettimeofday (&tm_end, NULL)

#define SHOW_TIME \
do {\
        printf ("time: %lu\n", 1000000 * (tm_end.tv_sec - tm_begin.tv_sec) + (tm_end.tv_usec - tm_begin.tv_usec)); \
} while (0)

struct IdxClient_key
{
        char ClientId[16];
        bool operator < (const IdxClient_key& s) const
        {
                int ret;
                ret = strcmp (ClientId, s.ClientId);
                if (ret < 0) {
                        return true;
                }
                return false;
        }
};

class ST_Client
{
public:
        ST_Client ()
        {
                memset (this, 0, sizeof (ST_Client));
        }

        char ClientId[16];
        char OpenDate[8];
};

int
main (int argc, char *argv[])
{
        int i = 0;
        std::map<IdxClient_key, ST_Client *> mapA;
        std::vector<IdxClient_key> vecA;
        IdxClient_key key;

        vecA.reserve (1000000);

        for (i = 0; i < 1000000; ++i) {
                ST_Client *p = new ST_Client;
                snprintf (p->ClientId, 16, "cid%d", i);
                /// snprintf (p->MemberId, 9, "%d", i);
                snprintf (p->OpenDate, 8, "20120508");

                memcpy (key.ClientId, p->ClientId, 16);
                mapA.insert (std::make_pair (key, p));
                vecA.push_back (key);
        }
        printf ("table size: %d\n", mapA.size ());

        std::vector<IdxClient_key>::iterator iter = vecA.begin ();
        std::vector<IdxClient_key>::iterator iter_end = vecA.end ();

BEGIN_CALC_TIME;
#if 1
        for (; iter != iter_end; ++iter) {
                std::map<IdxClient_key, ST_Client *>::iterator ret = mapA.find (*iter);
                if (ret == mapA.end ()) {
                        printf ("find error.\n");
                        return -1;
                }               
                mapA.erase (ret);
        }
#endif
END_CALC_TIME;
SHOW_TIME;
        printf ("table size: %d\n", mapA.size ());
}
   

论坛徽章:
0
4 [报告]
发表于 2012-05-09 12:58 |只看该作者
本帖最后由 wwwsq 于 2012-05-09 12:58 编辑

std::string会很愚蠢的进行很多malloc和memcpy的动作。

linux对malloc进行了很多优化,hpux可能是malloc不够好。在hpux下使用std::string,可以尝试一下google的tcmalloc

论坛徽章:
0
5 [报告]
发表于 2012-05-09 13:02 |只看该作者
wwwsq 发表于 2012-05-09 12:58
std::string会很愚蠢的进行很多malloc和memcpy的动作。

linux对malloc进行了很多优化,hpux可能是malloc ...

为啥非要用string类,想不明白

论坛徽章:
0
6 [报告]
发表于 2012-05-09 13:05 |只看该作者
doswin 发表于 2012-05-09 13:02
为啥非要用string类,想不明白



在对性能无所谓的时候,std::string还是蛮方便的。

论坛徽章:
0
7 [报告]
发表于 2012-05-09 13:08 |只看该作者
回复 1# keep_silence


    谢谢各位,string作为key,只是演示一下,请看第二段程序,使用字符串作为key,性能差距还是很大。

论坛徽章:
0
8 [报告]
发表于 2012-05-09 13:15 |只看该作者
keep_silence 发表于 2012-05-09 11:45
回复 2# hgrany

谢谢。我也觉得不是红黑树实现的问题,我还有一个测试程序,使用字符串作为key,性能也 ...

strcmp....简简单单的几行代码,没你说的那么恐怖。
倒是c++的类实现可能有问题是真的。

论坛徽章:
0
9 [报告]
发表于 2012-05-09 13:20 |只看该作者
keep_silence 发表于 2012-05-09 13:08
回复 1# keep_silence


map.set会malloc内存去构造IdxClient_key对象。

map.erase会释放IdxClient_key对象。

linux对内存释放也做了优化。。。。和malloc一起做的。。。。

论坛徽章:
0
10 [报告]
发表于 2012-05-09 14:16 |只看该作者
回复 9# wwwsq


有可能是这个问题,下面这个程序,HP比linux慢5倍,我按照这个思路再试试,谢谢了

#include <map>
#include <vector>
#include <list>
#include <stdio.h>
#include <string.h>

#include <sys/time.h>
#include <stdio.h>

static struct timeval tm_begin, tm_end;

#define BEGIN_CALC_TIME gettimeofday (&tm_begin, NULL)
#define END_CALC_TIME gettimeofday (&tm_end, NULL)

#define SHOW_TIME \
        do {\
                    printf ("time: %lu\n", 1000000 * (tm_end.tv_sec - tm_begin.tv_sec) + (tm_end.tv_usec - tm_begin.tv_usec)); \
        } while (0)


class ST_Client
{
        public:
                ST_Client ()
                {
                        memset (this, 0, sizeof (ST_Client));
                }

                char ClientId[16];
                char OpenDate[8];
};


int
main ()
{
        std::vector<ST_Client> vecA;
        ST_Client client;
BEGIN_CALC_TIME;
        for (int i = 0; i < 1000000; ++i) {
                vecA.push_back (client);
        }

        while (! vecA.empty ()) {
                vecA.pop_back ();
        }
END_CALC_TIME;
SHOW_TIME;

        printf ("size: %d\n", vecA.size ());
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP