]> mj.ucw.cz Git - libucw.git/blob - ucw/hashfunc-test.c
Released as 6.5.13.
[libucw.git] / ucw / hashfunc-test.c
1 /*
2  *      Checking the correctness of str_len() and hash_*() and proving, that
3  *      it is faster than the classical version ;-)
4  */
5
6 #include <ucw/hashfunc.h>
7
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <sys/time.h>
12
13 /* It will be divided by (10 + strlen()).  */
14 #define TEST_TIME       1000000
15
16 /* The shift of the string according to the alignment.  */
17 static uint alignment = 0;
18
19 static void
20 random_string(byte *str, int len)
21 {
22         int i;
23         for (i=0; i<len; i++)
24                 str[i] = random() % 255 + 1;
25         str[len] = 0;
26 }
27
28 static uint
29 elapsed_time(void)
30 {
31         static struct timeval last_tv, tv;
32         uint elapsed;
33         gettimeofday(&tv, NULL);
34         elapsed = (tv.tv_sec - last_tv.tv_sec) * 1000000 + (tv.tv_usec - last_tv.tv_usec);
35         last_tv = tv;
36         return elapsed;
37 }
38
39 int
40 main(int argc, char **argv)
41 {
42         byte *strings[] = {
43                 "",
44                 "a",
45                 "aa",
46                 "aaa",
47                 "aaaa",
48                 "aaaaa",
49                 "aaaaaa",
50                 "aaaaaaa",
51                 "aaaaaaaa",
52                 "aaaaaaaaa",
53                 "aaaaaaaaaa",
54                 "AHOJ",
55                 "\200aaaa",
56                 "\200",
57                 "\200\200",
58                 "\200\200\200",
59                 "\200\200\200\200",
60                 "\200\200\200\200\200",
61                 "kelapS treboR",
62                 "Robert Spalek",
63                 "uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu",
64                 "********************************",
65                 "****************************************************************",
66                 NULL
67         };
68         int lengths[] = {
69                 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
70                 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
71                 30, 40, 50, 60, 70, 80, 90, 100,
72                 200, 300, 400, 500, 600, 700, 800, 900, 1000,
73                 2000, 4000, 8000, 16000, 32000, 64000,
74                 -1
75         };
76         int i;
77         if (argc > 1)
78                 alignment = atoi(argv[1]);
79         printf("Alignment set to %d\n", alignment);
80         for (i=0; strings[i]; i++)
81                 if (strlen(strings[i]) != str_len(strings[i]))
82                         die("Internal str_len() error on string %d", i);
83         printf("%d strings tested OK\n", i);
84         for (i=0; strings[i]; i++)
85         {
86                 uint h1, h2;
87                 h1 = hash_string(strings[i]);
88                 h2 = hash_string_nocase(strings[i]);
89                 if (h1 != hash_block(strings[i], str_len(strings[i])))
90                         die("Internal hash_string() error on string %d", i);
91                 printf("hash %2d = %08x %08x", i, h1, h2);
92                 if (h1 == h2)
93                         printf(" upper case?");
94                 printf("\n");
95         }
96         for (i=0; lengths[i] >= 0; i++)
97         {
98                 byte str[lengths[i] + 1 + alignment];
99                 uint count = TEST_TIME / (lengths[i] + 10);
100                 uint el1 = 0, el2 = 0, elh = 0, elhn = 0;
101                 uint tot1 = 0, tot2 = 0, hash = 0, hashn = 0;
102                 uint j;
103                 for (j=0; j<count; j++)
104                 {
105                         random_string(str + alignment, lengths[i]);
106                         elapsed_time();
107                         /* Avoid "optimizing" by gcc, since the functions are
108                          * attributed PURE.  */
109                         tot1 += strlen(str + alignment);
110                         el1 += elapsed_time();
111                         tot2 += str_len(str + alignment);
112                         el2 += elapsed_time();
113                         hash ^= hash_string(str + alignment);
114                         elh += elapsed_time();
115                         hashn ^= hash_string_nocase(str + alignment);
116                         elhn += elapsed_time();
117                 }
118                 if (tot1 != tot2)
119                         die("Internal error during test %d", i);
120                 printf("Test %d: strlen = %d, passes = %d, classical = %d usec, speedup = %.4f\n",
121                         i, lengths[i], count, el1, (el1 + 0.) / el2);
122                 printf("\t\t total hash = %08x/%08x, hash time = %d/%d usec\n", hash, hashn, elh, elhn);
123         }
124 /*
125         printf("test1: %d\n", hash_modify(10000000, 10000000, 99777555));
126         printf("test1: %d, %d\n", i, hash_modify(i, lengths[i-2], 99777333));
127         printf("test1: %d, %d\n", i, hash_modify(lengths[i-2], i, 99777333));
128         printf("test1: %d,%d,%d->%d\n", i, i*3-2, i*i, hash_modify(4587, i*3-2, i*i));
129         printf("test1: %d\n", hash_modify(lengths[5], 345, i));
130 */
131         return 0;
132 }