/*
* Copyright (c) 2002-2005 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*/
#include "sm/generic.h"
SM_RCSID("@(#)$Id: b-lists.c,v 1.10 2005/04/14 17:14:02 ca Exp $")
#include "sm/assert.h"
#include "sm/magic.h"
#include "sm/heap.h"
#include "sm/test.h"
#include "sm/queue.h"
#include <stdio.h>
#include <sys/time.h>
#define toseconds(x, y) (x.tv_sec - y.tv_sec)
static int Verbose = 0;
struct timeval t1, t2;
#define GT(ti) do { \
if (gettimeofday((ti), NULL) < 0) \
perror("gettimeofday"); \
} while (0)
#define START() GT(&t1)
#define END() GT(&t2)
#define DONE() do { if (Verbose > 0) \
printf("function time: %ld seconds\n", toseconds(t2, t1)); \
} while (0)
#define ELEMS 1024
#define ITER 100
struct tq_entry
{
int item;
TAILQ_ENTRY(tq_entry) entries;
};
TAILQ_HEAD(tq, tq_entry) tq_head;
typedef struct tq_entry tq_entry_T;
typedef struct tq tq_T;
static void
test_tq(int iter)
{
int i, j, old, count;
tq_T head;
tq_entry_T *tqe, *np;
TAILQ_INIT(&head);
SM_TEST(TAILQ_EMPTY(&head));
tqe = (tq_entry_T *) sm_malloc(ELEMS * sizeof(*tqe));
for (i = 0; i < ELEMS; i++)
tqe[i].item = i;
START();
for (j = 0; j < iter; j++)
{
TAILQ_INIT(&head);
for (i = 0; i < ELEMS; i++)
{
TAILQ_INSERT_TAIL(&head, &(tqe[i]), entries);
}
old = -1;
count = 0;
TAILQ_FOREACH(np, &head, entries)
{
SM_TEST(old < np->item);
old = np->item;
++count;
}
}
END();
DONE();
sm_free(tqe);
}
struct sl_entry
{
int item;
SLIST_ENTRY(sl_entry) entries;
};
SLIST_HEAD(sl, sl_entry) sl_head;
typedef struct sl_entry sl_entry_T;
typedef struct sl sl_T;
static void
test_sl(int iter)
{
int i, j, old, count;
sl_T head;
sl_entry_T *sle, *np;
SLIST_INIT(&head);
SM_TEST(SLIST_EMPTY(&head));
sle = (sl_entry_T *) sm_malloc(ELEMS * sizeof(*sle));
for (i = 0; i < ELEMS; i++)
sle[i].item = i;
START();
for (j = 0; j < iter; j++)
{
SLIST_INIT(&head);
for (i = 0; i < ELEMS; i++)
{
/* tail doesn't work... */
SLIST_INSERT_HEAD(&head, &(sle[i]), entries);
}
old = ELEMS + 1;
count = 0;
SLIST_FOREACH(np, &head, entries)
{
SM_TEST(old > np->item);
old = np->item;
++count;
}
}
END();
DONE();
sm_free(sle);
}
struct li_entry
{
int item;
LIST_ENTRY(li_entry) entries;
};
LIST_HEAD(li, li_entry) li_head;
typedef struct li_entry li_entry_T;
typedef struct li li_T;
static void
test_li(int iter)
{
int i, j, old, count;
li_T head;
li_entry_T *lie, *np;
LIST_INIT(&head);
SM_TEST(LIST_EMPTY(&head));
lie = (li_entry_T *) sm_malloc(ELEMS * sizeof(*lie));
for (i = 0; i < ELEMS; i++)
lie[i].item = i;
START();
for (j = 0; j < iter; j++)
{
LIST_INIT(&head);
for (i = 0; i < ELEMS; i++)
{
/* tail doesn't work... */
LIST_INSERT_HEAD(&head, &(lie[i]), entries);
}
old = ELEMS + 1;
count = 0;
LIST_FOREACH(np, &head, entries)
{
SM_TEST(old > np->item);
old = np->item;
++count;
}
}
END();
DONE();
sm_free(lie);
}
struct cq_entry
{
int item;
CIRCLEQ_ENTRY(cq_entry) entries;
};
CIRCLEQ_HEAD(cq, cq_entry) cq_head;
typedef struct cq_entry cq_entry_T;
typedef struct cq cq_T;
static void
test_cq(int iter)
{
int i, j, old, count;
cq_T head;
cq_entry_T *cqe, *np;
CIRCLEQ_INIT(&head);
SM_TEST(CIRCLEQ_EMPTY(&head));
cqe = (cq_entry_T *) sm_malloc(ELEMS * sizeof(*cqe));
for (i = 0; i < ELEMS; i++)
cqe[i].item = i;
START();
for (j = 0; j < iter; j++)
{
CIRCLEQ_INIT(&head);
for (i = 0; i < ELEMS; i++)
{
CIRCLEQ_INSERT_TAIL(&head, &(cqe[i]), entries);
}
old = -1;
count = 0;
CIRCLEQ_FOREACH(np, &head, entries)
{
SM_TEST(old < np->item);
old = np->item;
++count;
}
}
END();
DONE();
sm_free(cqe);
}
struct sq_entry
{
int item;
SIMPLEQ_ENTRY(sq_entry) entries;
};
SIMPLEQ_HEAD(sq, sq_entry) sq_head;
typedef struct sq_entry sq_entry_T;
typedef struct sq sq_T;
static void
test_sq(int iter)
{
int i, j, old, count;
sq_T head;
sq_entry_T *sqe, *np;
SIMPLEQ_INIT(&head);
SM_TEST(SIMPLEQ_EMPTY(&head));
sqe = (sq_entry_T *) sm_malloc(ELEMS * sizeof(*sqe));
for (i = 0; i < ELEMS; i++)
sqe[i].item = i;
START();
for (j = 0; j < iter; j++)
{
SIMPLEQ_INIT(&head);
for (i = 0; i < ELEMS; i++)
{
SIMPLEQ_INSERT_TAIL(&head, &(sqe[i]), entries);
}
old = -1;
count = 0;
SIMPLEQ_FOREACH(np, &head, entries)
{
SM_TEST(old < np->item);
old = np->item;
++count;
}
}
END();
DONE();
sm_free(sqe);
}
int
main(int argc, char *argv[])
{
int c, iter;
iter = ITER;
while ((c = getopt(argc, argv, "l:")) != -1)
{
switch (c)
{
case 'l':
iter = atoi(optarg);
break;
#if 0
default:
usage(argv[0]);
return(1);
#endif /* 0 */
}
}
if (iter > ITER)
Verbose++;
sm_test_begin(argc, argv, "test lists");
if (Verbose > 0)
printf("circleq: ");
test_cq(iter);
if (Verbose > 0)
printf("tailq: ");
test_tq(iter);
if (Verbose > 0)
printf("slist: ");
test_sl(iter);
if (Verbose > 0)
printf("list: ");
test_li(iter);
if (Verbose > 0)
printf("simpleq: ");
test_sq(iter);
return sm_test_end();
}
#if 0
cube.dev-lab$ ./b-lists -l 100000
circleq: function time: 18 seconds
tailq: function time: 21 seconds
slist: function time: 8 seconds
list: function time: 21 seconds
simpleq: function time: 16 seconds
zardoc.esmtp.org$ ./b-lists -l 100000
circleq: function time: 9 seconds
tailq: function time: 9 seconds
slist: function time: 7 seconds
list: function time: 9 seconds
simpleq: function time: 7 seconds
sun8.dev-lab$ ./b-lists -l 100000
circleq: function time: 14 seconds
tailq: function time: 13 seconds
slist: function time: 11 seconds
list: function time: 13 seconds
simpleq: function time: 13 seconds
aix$ $ ./b-lists -l 100000
circleq: function time: 20 seconds
tailq: function time: 19 seconds
slist: function time: 18 seconds
list: function time: 19 seconds
simpleq: function time: 18 seconds
k7.esmtp.org$ ./b-lists -l 100000
circleq: function time: 7 seconds
tailq: function time: 6 seconds
slist: function time: 4 seconds
list: function time: 6 seconds
simpleq: function time: 5 seconds
512000005 of 512000005 tests completed successfully
k7.esmtp.org$ ./b-lists -l 1000000
circleq: function time: 63 seconds
tailq: function time: 61 seconds
slist: function time: 43 seconds
list: function time: 63 seconds
simpleq: function time: 49 seconds
825032709 of 825032709 tests completed successfully
#endif /* 0 */
syntax highlighted by Code2HTML, v. 0.9.1