Skip to content

Commit 75e2afc

Browse files
committed
.
1 parent f8fc027 commit 75e2afc

6 files changed

Lines changed: 98 additions & 27 deletions

File tree

bench/bench_sort/.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,4 +346,5 @@ shuffle.py
346346
perftest/
347347
.idea/
348348
.claude/
349-
a.out
349+
a.out
350+
*.exe

bench/bench_sort/RESULTS.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
# Sort Benchmarks
22

3-
| OS | Compiler | qsort | msort | tsort | pdqsort |
4-
|--------|----------|----------|----------|----------|----------|
3+
| OS | Compiler | qsort | msort | tsort | pdqsort |
4+
|--------|----------|--------|-------|-------|------|
55
| MacOS | gcc | 1.228499 | 0.850596 | 0.802016 | 0.800305 |
66
| MacOS | clang | 1.214308 | 0.806101 | 1.402682 | 0.778406 |
77
| MacOS | tcc | 1.754751 | 2.518867 | 2.252877 | 2.782485 |
8-
| - | - | - | - | - | - |
8+
| - | - | - | - | - | - |
99
| Ubuntu | gcc | 3.103605 | 2.512247 | 1.394739 | 1.316805 |
1010
| Ubuntu | clang | 2.891076 | 1.250306 | 1.331671 | 1.245906 |
1111
| Ubuntu | tcc | 3.689096 | 3.847597 | 3.569996 | 4.680283 |
12-
12+
| - | - | - | - | - | - |
13+
|Windows | gcc(MinGW64)| 2301.69|1150.17|1132.98|1071.00|
14+
|Windows| clang | 1624.76|987.45|876.54|851.41|
15+
|Windows | MSVC |1751.45|1644.03|1477.77|1468.00|
16+
|Windows | tcc |10610.94|6275.81|5829.98|8354.42|

bench/bench_sort/main.c

Lines changed: 66 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,53 @@
33
#include <stdlib.h>
44
#include <string.h>
55
#include <time.h>
6+
#include <stdio.h>
7+
8+
#if defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)
9+
10+
#include <windows.h>
11+
12+
typedef LARGE_INTEGER watch;
13+
14+
static watch now() {
15+
watch t;
16+
QueryPerformanceCounter(&t);
17+
return t;
18+
}
19+
20+
static double duration(const watch t_beg, const watch t_end) {
21+
LARGE_INTEGER freq;
22+
QueryPerformanceFrequency(&freq);
23+
double ms = (double) (t_end.QuadPart - t_beg.QuadPart) * 1000.0 / (double) freq.QuadPart;
24+
return ms > 0 ? ms : -ms;
25+
}
26+
27+
28+
#elif defined(__MINGW32__) || defined(__MINGW64__) || defined(__GNUC__) || defined(__TINYC__)
29+
30+
631
#include <sys/time.h>
32+
#include <time.h>
33+
34+
typedef struct timeval watch;
35+
36+
static watch now() {
37+
watch tv;
38+
gettimeofday(&tv, NULL);
39+
return tv;
40+
}
41+
42+
static double duration(const watch t_beg, const watch t_end) {
43+
double ms = (t_end.tv_sec - t_beg.tv_sec) * 1000.0 +
44+
(t_end.tv_usec - t_beg.tv_usec) / 1000.0;
45+
return ms > 0 ? ms : -ms;
46+
}
47+
48+
49+
#else
50+
#error Unsupported compiler/platform
51+
#endif
52+
753
#include "tsort.h"
854
#include "msort.h"
955
#include "pdqsort.h"
@@ -60,45 +106,45 @@ int sort_test() {
60106
DTYPE *target = (DTYPE *) calloc(N, sizeof(DTYPE));
61107

62108

63-
struct timeval bgn;
64-
struct timeval end;
109+
watch bgn;
110+
watch end;
65111
double m_diff = 0;
66112
double q_diff = 0;
67113
double t_diff = 0;
68114
double p_diff = 0;
69115
double r_diff = 0;
70116
for (int i = 0; i < ALGORITHMS * REPEAT; i++) {
71117
memcpy(target, arr, N * sizeof(int));
72-
gettimeofday(&bgn, NULL);
118+
bgn = now();
73119
switch (i % ALGORITHMS) {
74120
case 0: {
75121
qsort(target, N, sizeof(DTYPE), compare);
76-
gettimeofday(&end, NULL);
77-
q_diff += end.tv_sec + end.tv_usec / 1000000.0 - bgn.tv_sec - bgn.tv_usec / 1000000.0;
122+
end = now();
123+
q_diff += duration(bgn, end);
78124
};
79125
break;
80126
case 1: {
81127
msort(target, N, sizeof(DTYPE), compare);
82-
gettimeofday(&end, NULL);
83-
m_diff += end.tv_sec + end.tv_usec / 1000000.0 - bgn.tv_sec - bgn.tv_usec / 1000000.0;
128+
end = now();
129+
m_diff += duration(bgn, end);
84130
};
85131
break;
86132
case 2: {
87133
tsort(target, N, sizeof(DTYPE), compare);
88-
gettimeofday(&end, NULL);
89-
t_diff += end.tv_sec + end.tv_usec / 1000000.0 - bgn.tv_sec - bgn.tv_usec / 1000000.0;
134+
end = now();
135+
t_diff += duration(bgn, end);
90136
};
91137
break;
92138
case 3: {
93139
pdqsort(target, N, sizeof(DTYPE), compare);
94-
gettimeofday(&end, NULL);
95-
p_diff += end.tv_sec + end.tv_usec / 1000000.0 - bgn.tv_sec - bgn.tv_usec / 1000000.0;
140+
end = now();
141+
p_diff += duration(bgn, end);
96142
}
97143
break;
98144
case 4: {
99145
rsort64(target, N);
100-
gettimeofday(&end, NULL);
101-
r_diff += end.tv_sec + end.tv_usec / 1000000.0 - bgn.tv_sec - bgn.tv_usec / 1000000.0;
146+
end = now();
147+
r_diff += duration(bgn, end);
102148
}
103149
break;
104150
default: {
@@ -110,12 +156,14 @@ int sort_test() {
110156
puts("Not sorted");
111157
}
112158
}
113-
printf("qsort: %f\n", q_diff);
114-
printf("msort: %f\n", m_diff);
159+
printf("qsort: %.2fms\n", q_diff);
160+
printf("msort: %.2fms\n", m_diff);
161+
162+
printf("tsort: %.2fms\n", t_diff);
163+
printf("pdqsort: %.2fms\n", p_diff);
164+
printf("rsort: %.2fms\n", r_diff);
115165

116-
printf("tsort: %f\n", t_diff);
117-
printf("pdqsort: %f\n", p_diff);
118-
printf("rsort: %f\n", r_diff);
166+
printf("|%.2f|%.2f|%.2f|%.2f|\n",q_diff,m_diff,t_diff,p_diff);
119167
return 0;
120168
}
121169

bench/bench_sort/pdqsort.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,21 @@
1111
#define PDQ_MAX_STACK 64
1212

1313

14+
#if defined(_MSC_VER)
15+
#define PDQ_LIKELY(x) (x)
16+
#define PDQ_UNLIKELY(x) (x)
17+
#else
18+
#define PDQ_LIKELY(x) __builtin_expect(!!(x), 1)
19+
#define PDQ_UNLIKELY(x) __builtin_expect(!!(x), 0)
20+
#endif
21+
1422
static inline void pdq__swap(unsigned char *a, unsigned char *b, size_t n) {
15-
if (__builtin_expect(n == 8, 1)) {
23+
if (PDQ_LIKELY(n == 8)) {
1624
uint64_t t;
1725
memcpy(&t, a, 8);
1826
memcpy(a, b, 8);
1927
memcpy(b, &t, 8);
20-
} else if (__builtin_expect(n == 4, 0)) {
28+
} else if (PDQ_UNLIKELY(n == 4)) {
2129
uint32_t t;
2230
memcpy(&t, a, 4);
2331
memcpy(a, b, 4);

opencstl/pdqsort.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,21 @@
1111
#define PDQ_MAX_STACK 64
1212

1313

14+
#if defined(_MSC_VER)
15+
#define PDQ_LIKELY(x) (x)
16+
#define PDQ_UNLIKELY(x) (x)
17+
#else
18+
#define PDQ_LIKELY(x) __builtin_expect(!!(x), 1)
19+
#define PDQ_UNLIKELY(x) __builtin_expect(!!(x), 0)
20+
#endif
21+
1422
static inline void pdq__swap(unsigned char *a, unsigned char *b, size_t n) {
15-
if (__builtin_expect(n == 8, 1)) {
23+
if (PDQ_LIKELY(n == 8)) {
1624
uint64_t t;
1725
memcpy(&t, a, 8);
1826
memcpy(a, b, 8);
1927
memcpy(b, &t, 8);
20-
} else if (__builtin_expect(n == 4, 0)) {
28+
} else if (PDQ_UNLIKELY(n == 4)) {
2129
uint32_t t;
2230
memcpy(&t, a, 4);
2331
memcpy(a, b, 4);

opencstl/watch.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ static watch now() {
5252
}
5353

5454
static double duration(const watch t_beg, const watch t_end) {
55+
LARGE_INTEGER freq;
56+
QueryPerformanceFrequency(&freq);
5557
double ms = (double) (t_end.QuadPart - t_beg.QuadPart) * 1000.0 / (double) freq.QuadPart;
5658
return ms > 0 ? ms : -ms;
5759
}

0 commit comments

Comments
 (0)