forked from yanjiew1/linux23q1-timsort
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.c
138 lines (116 loc) · 2.92 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include "list.h"
#include "list_sort.h"
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <stdint.h>
#include <stdbool.h>
typedef struct element {
struct list_head list;
int val;
int seq;
} element_t;
#define SAMPLES ((1 << 20) + 20)
static void create_sample(struct list_head *head, element_t *space, int samples)
{
for (int i = 0; i < samples; i++) {
element_t *elem = space+i;
elem->val = rand();
elem->seq = i;
list_add_tail(&elem->list, head);
}
}
static void copy_list(struct list_head *from, struct list_head *to, element_t *space)
{
if (list_empty(from))
return;
element_t *entry;
list_for_each_entry(entry, from, list) {
element_t *copy = space++;
copy->val = entry->val;
copy->seq = entry->seq;
list_add_tail(©->list, to);
}
}
#if 0
static void free_list(struct list_head *head)
{
element_t *entry, *safe;
list_for_each_entry_safe(entry, safe, head, list) {
list_del(&entry->list);
free(entry);
}
}
#endif
int compare(void *priv, const struct list_head *a, const struct list_head *b)
{
if (a == b)
return 0;
int res = list_entry(a, element_t, list)->val -
list_entry(b, element_t, list)->val;
if (priv) {
*((int *)priv) += 1;
}
return res;
}
bool check_list(struct list_head *head, int count)
{
if (list_empty(head))
return count == 0;
element_t *entry, *safe;
list_for_each_entry_safe(entry, safe, head, list) {
if (entry->list.next != head) {
if (entry->val > safe->val ||
(entry->val == safe->val && entry->seq > safe->seq)) {
return false;
}
}
}
return true;
}
typedef void (*test_func_t)(void *priv, struct list_head *head,
list_cmp_func_t cmp);
typedef struct test {
test_func_t fp;
char *name;
} test_t;
int main(void)
{
struct list_head sample_head, warmdata_head, testdata_head;
element_t *samples, *warmdata, *testdata;
int count;
int nums = SAMPLES;
srand(1050);
test_t tests[] = {
{ list_sort, "list_sort" },
{ list_sort_old, "list_sort_old" },
{ shiverssort, "shiverssort" },
{ timsort, "timsort" },
{ NULL, NULL } },
*test = tests;
INIT_LIST_HEAD(&sample_head);
samples = malloc(sizeof(*samples) * SAMPLES);
warmdata = malloc(sizeof(*warmdata) * SAMPLES);
testdata = malloc(sizeof(*testdata) * SAMPLES);
create_sample(&sample_head, samples, nums);
while (test->fp != NULL) {
printf("==== Testing %s ====\n", test->name);
/* Warm up */
INIT_LIST_HEAD(&warmdata_head);
INIT_LIST_HEAD(&testdata_head);
copy_list(&sample_head, &testdata_head, testdata);
copy_list(&sample_head, &warmdata_head, warmdata);
test->fp(&count, &warmdata_head, compare);
/* Test */
clock_t begin;
count = 0;
begin = clock();
test->fp(&count, &testdata_head, compare);
printf(" Elapsed time: %ld\n", clock() - begin);
printf(" Comparisons: %d\n", count);
printf(" List is %s\n",
check_list(&testdata_head, nums) ? "sorted" : "not sorted");
test++;
}
return 0;
}