免费注册 查看新帖 |

Chinaunix

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

[C] list.h中的list 和 queue.h中的STAILQ 的性能测试 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-07-20 21:15 |只看该作者 |倒序浏览
Linux内核源码中的“list.h”和FreeBSD源码中的"queue.h"中的STAILQ都可以被用来做FIFO的队列。
由于对程序的效率非常关心,因此我测试了这两个实现的性能:

在一次测试中,是将一个N=1000000个事先分配好的object进行如下操作:
  • 将N个object依次添加到队列末尾
  • 进行N次的删除队列首元素操作


除了list和STAILQ外,我还自己实现了一个MYQ。MYQ比起STAILQ所需要的内存更少,不过性能似乎还不如STAILQ。。。

原本以为list的效率应该和STAILQ差不多,结果却发现效率相差将近一倍。个人感觉STAILQ的效率应该几乎是最优的了。
下面是测试结果:

python timeit.py vs-LIST.exe
Testing LIST...
Time used: 10.703
python timeit.py vs-STAILQ.exe
Testing STAILQ...
Time used: 5.843
python timeit.py vs-MYQ.exe
Testing MYQ...
Time used: 5.937

程序如下:
#include <stdio.h>

#include "list.h"
#include "queue.h"

#define STAILQ_TEST (1)
#define LIST_TEST   (2)
#define MYQ_TEST    (3)

#ifndef TEST
#error TEST must be defined to STAILQ_TEST or LIST_TEST
#endif

#define REPEAT      (500)
#define NOBJECTS    (1000000)

struct object{
    char anything[7];
#if TEST == LIST_TEST
    struct list_head list_entry;
#elif TEST == STAILQ_TEST
    STAILQ_ENTRY(object) stailq_entry;
#elif TEST == MYQ_TEST
    struct object *myq_next;
#endif
};

struct object objects[NOBJECTS]; // all objects

STAILQ_HEAD(__stailq, object) the_stailq = STAILQ_HEAD_INITIALIZER(the_stailq); // the stailq

LIST_HEAD(the_list);

#if TEST == STAILQ_TEST
static void test_stailq()
{
    int t;
    puts("Testing STAILQ...");
    for (t = 0; t < REPEAT; t++) {
        int i;

        for (i = 0; i < NOBJECTS; i++) {
            STAILQ_INSERT_TAIL(&the_stailq, objects+i, stailq_entry);
        }
        for (i = 0; i < NOBJECTS; i++) {
            STAILQ_REMOVE_HEAD(&the_stailq, stailq_entry);
        }
    }
}
#elif TEST == LIST_TEST
static void test_list()
{
    int t;
    puts("Testing LIST...");
    for (t = 0; t < REPEAT; t++) {
        int i;

        for (i = 0; i < NOBJECTS; i++) {
            list_add_tail( (&(objects[i].list_entry)), (&the_list) );
        }
        for (i = 0; i < NOBJECTS; i++) {
            list_del( (the_list.next) );
        }
    }
}
#elif TEST == MYQ_TEST

struct {
    struct object *head;
    struct object **lastp;
} the_myq = {
    NULL, &(the_myq.head),
};

#define myq_push(new, q)            \
    do {                            \
        *((q)->lastp) = new;        \
        (q)->lastp = &new->myq_next;    \
    } while(0)

#define myq_pop(q)  \
    do {    \
        if ((q)->lastp == &((q)->head->myq_next) ) {   \
            (q)->lastp = &((q)->head);  \
        }   \
        (q)->head = (q)->head->myq_next;    \
    } while(0)

static void test_myq()
{
    int t;
    puts("Testing MYQ...");
    for (t = 0; t < REPEAT; t++) {
        int i;

        for (i = 0; i < NOBJECTS; i++) {
            myq_push( (&(objects[i])), (&the_myq) );
        }
        for (i = 0; i < NOBJECTS; i++) {
            myq_pop( &the_myq );
        }
    }
}

#endif //TEST == STAILQ_TEST


int main()
{
#if TEST==LIST_TEST
    test_list();
#elif TEST == STAILQ_TEST
    test_stailq();
#elif TEST == MYQ_TEST
    test_myq();
#else
#error TEST is wrong.
#endif
    return 0;
}


我把程序放在附件里,有兴趣的人可以下载,呵呵。

queuevslist.rar

9.42 KB, 下载次数: 58

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:53:172015亚冠之水原三星
日期:2015-06-02 16:34:202015年亚冠纪念徽章
日期:2015-10-19 18:13:37程序设计版块每日发帖之星
日期:2015-11-08 06:20:00
2 [报告]
发表于 2009-07-20 21:41 |只看该作者
不错

评分

参与人数 1可用积分 -5 收起 理由
converse -5 恶意灌水,能不能回复有点技术含量的回 ...

查看全部评分

论坛徽章:
0
3 [报告]
发表于 2009-07-20 23:08 |只看该作者
STAILQ 性能优于 list   =>   BSD 性能忧于 Linux   =>  BSDer 比 Linuxer 强

其实 list 是双向循环链表,STAILQ 是单向非循环链表
STAILQ 的插入需要重指三个指针(包含一个指针清 0 操作,会快一点)
list 需要重指四个指针
所以当然是 STAILQ 要快

论坛徽章:
0
4 [报告]
发表于 2009-07-20 23:29 |只看该作者
搞错了,,,自己写的MYQ其实就是STAILQ。。。而且实现得不好。。。虽然myq_push中只需要2句赋值,但是myq_pop中的判断似乎比STAILQ_REMOVE_HEAD中的判断更加昂贵,总体速度也比STAILQ稍差。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP