Reputation: 1275
I am working on an Linux project, and I want to evaluate two main data structures: RBtree and Hash list.
So I got 2 C programs to evaluate their performance (the count of instructions and CPU cycles).
// Hlist_test.c
#include "hlist.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#define MAX_ADDR 10
/* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */
#define GOLDEN_RATIO_PRIME_32 0x9e370001UL
static inline uint32_t hash_32(uint32_t val, unsigned int bits)
{
/* On some cpus multiply is faster, on others gcc will do shifts */
uint32_t hash = val * GOLDEN_RATIO_PRIME_32;
/* High bits are more random, so use them. */
return hash >> (32 - bits);
}
struct hdata_node {
unsigned int data;
struct hlist_node list;
};
unsigned int a[] = {0x1000, 0x4000, 0x3000, 0x6000, 0x9000, 0x7000, 0x2000, 0x5000, 0x8000};
static struct hdata_node hnodes[MAX_ADDR] = {
{.data = 0x1000},
{.data = 0x4000},
{.data = 0x3000},
{.data = 0x6000},
{.data = 0x9000},
{.data = 0x7000},
{.data = 0x2000},
{.data = 0x5000},
{.data = 0x8000},
{.data = 0x9100},
};
int main(int argc, char **argv)
{
struct hlist_head htable[MAX_ADDR];
struct hdata_node *hnode = NULL;
struct hlist_node *hlist = NULL, *n = NULL;
int i = 0, quit = 1, opt = 0, key;
unsigned int data;
for(i = 0; i < MAX_ADDR; i++) {
INIT_HLIST_HEAD(&htable[i]);
INIT_HLIST_NODE(&hnodes[i].list);
}
for (i = 0;i < MAX_ADDR; i++) {
key = hnodes[i].data >> 28;
hlist_add_head(&hnodes[i].list, &htable[key]);
}
hlist_for_each_entry_safe(hnode, hlist, n, &htable[9], list) {
if (hnode->data == 0x9000) {
//printf("FOUND\n");
break;
}
}
for (i = 0;i < MAX_ADDR; i++) {
key = hnodes[i].data >> 28;
hlist_del(&hnodes[i].list);
}
return 0;
}
And rbtree_test.c
/**
* Based on definition of rbtree in Linux Kernel
*
* @author skywang
* @date 2013/11/18
*/
#include <stdio.h>
#include <stdlib.h>
#include "rbtree.h"
#define LENGTH(a) ( (sizeof(a)) / (sizeof(a[0])) )
typedef int Type;
struct my_node {
struct rb_node rb_node;
Type key;
// ... user data;
};
/*
* Lookup node.
*/
struct my_node *my_search(struct rb_root *root, Type key)
{
struct rb_node *rbnode = root->rb_node;
while (rbnode!=NULL)
{
struct my_node *mynode = container_of(rbnode, struct my_node, rb_node);
if (key < mynode->key)
rbnode = rbnode->rb_left;
else if (key > mynode->key)
rbnode = rbnode->rb_right;
else
return mynode;
}
return NULL;
}
/*
*
*/
int my_insert(struct rb_root *root, Type key)
{
struct my_node *mynode;
struct rb_node **tmp = &(root->rb_node), *parent = NULL;
/* Figure out where to put new node */
while (*tmp)
{
struct my_node *my = container_of(*tmp, struct my_node, rb_node);
parent = *tmp;
if (key < my->key)
tmp = &((*tmp)->rb_left);
else if (key > my->key)
tmp = &((*tmp)->rb_right);
else
return -1;
}
if ((mynode=malloc(sizeof(struct my_node))) == NULL)
return -1;
mynode->key = key;
/* Add new node and rebalance tree. */
rb_link_node(&mynode->rb_node, parent, tmp);
rb_insert_color(&mynode->rb_node, root);
return 0;
}
/*
* Delete node
*/
void my_delete(struct rb_root *root, Type key)
{
struct my_node *mynode;
if ((mynode = my_search(root, key)) == NULL)
return ;
// delete mynode
rb_erase(&mynode->rb_node, root);
free(mynode);
}
/*
* print rbtree
*/
static void print_rbtree(struct rb_node *tree, Type key, int direction)
{
if(tree != NULL)
{
if(direction==0)
printf("%2d(B) is root\n", key);
else
printf("%2d(%s) is %2d's %6s child\n", key, rb_is_black(tree)?"B":"R", key, direction==1?"right" : "left");
if (tree->rb_left)
print_rbtree(tree->rb_left, rb_entry(tree->rb_left, struct my_node, rb_node)->key, -1);
if (tree->rb_right)
print_rbtree(tree->rb_right,rb_entry(tree->rb_right, struct my_node, rb_node)->key, 1);
}
}
void my_print(struct rb_root *root)
{
if (root!=NULL && root->rb_node!=NULL)
print_rbtree(root->rb_node, rb_entry(root->rb_node, struct my_node, rb_node)->key, 0);
}
void main()
{
unsigned int a[] = {0x1000, 0x4000, 0x3000, 0x6000, 0x9000, 0x7000, 0x2000, 0x5000, 0x8000};
int i, ilen=LENGTH(a);
struct rb_root mytree = RB_ROOT;
printf("== Original data: ");
for(i=0; i<ilen; i++)
printf("0x%x ", a[i]);
printf("\n");
for (i=0; i < ilen; i++)
{
my_insert(&mytree, a[i]);
}
// Check tree searching
my_search(&mytree, a[0]);
for (i=0; i<ilen; i++) {
my_delete(&mytree, a[i]);
}
}
Both programs have 10 items to be inserted, deleted and searched in the data structure.
I am not sure if they are OK for benchmarking their performance?
Or is there any other formal benchtests for Hlist and RBTree I can refer to?
Upvotes: 1
Views: 21