]>
Commit | Line | Data |
---|---|---|
97020474 SP |
1 | /* Measure strncmp functions. |
2 | Copyright (C) 2013 Free Software Foundation, Inc. | |
3 | This file is part of the GNU C Library. | |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Lesser General Public | |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Lesser General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Lesser General Public | |
16 | License along with the GNU C Library; if not, see | |
17 | <http://www.gnu.org/licenses/>. */ | |
18 | ||
19 | #define TEST_MAIN | |
20 | #define TEST_NAME "strncmp" | |
21 | #include "bench-string.h" | |
22 | ||
23 | typedef int (*proto_t) (const char *, const char *, size_t); | |
24 | int simple_strncmp (const char *, const char *, size_t); | |
25 | int stupid_strncmp (const char *, const char *, size_t); | |
26 | ||
27 | IMPL (stupid_strncmp, 0) | |
28 | IMPL (simple_strncmp, 0) | |
29 | IMPL (strncmp, 1) | |
30 | ||
31 | int | |
32 | simple_strncmp (const char *s1, const char *s2, size_t n) | |
33 | { | |
34 | int ret = 0; | |
35 | ||
36 | while (n-- && (ret = *(unsigned char *) s1 - * (unsigned char *) s2++) == 0 | |
37 | && *s1++); | |
38 | return ret; | |
39 | } | |
40 | ||
41 | int | |
42 | stupid_strncmp (const char *s1, const char *s2, size_t n) | |
43 | { | |
44 | size_t ns1 = strnlen (s1, n) + 1, ns2 = strnlen (s2, n) + 1; | |
45 | int ret = 0; | |
46 | ||
47 | n = ns1 < n ? ns1 : n; | |
48 | n = ns2 < n ? ns2 : n; | |
49 | while (n-- && (ret = *(unsigned char *) s1++ - * (unsigned char *) s2++) == 0); | |
50 | return ret; | |
51 | } | |
52 | ||
53 | static void | |
54 | do_one_test (impl_t *impl, const char *s1, const char *s2, size_t n, | |
55 | int exp_result) | |
56 | { | |
57 | if (HP_TIMING_AVAIL) | |
58 | { | |
59 | hp_timing_t start __attribute ((unused)); | |
60 | hp_timing_t stop __attribute ((unused)); | |
61 | hp_timing_t best_time = ~ (hp_timing_t) 0; | |
62 | size_t i; | |
63 | ||
64 | for (i = 0; i < 32; ++i) | |
65 | { | |
66 | HP_TIMING_NOW (start); | |
67 | CALL (impl, s1, s2, n); | |
68 | HP_TIMING_NOW (stop); | |
69 | HP_TIMING_BEST (best_time, start, stop); | |
70 | } | |
71 | ||
72 | printf ("\t%zd", (size_t) best_time); | |
73 | } | |
74 | } | |
75 | ||
76 | static void | |
77 | do_test_limit (size_t align1, size_t align2, size_t len, size_t n, int max_char, | |
78 | int exp_result) | |
79 | { | |
80 | size_t i, align_n; | |
81 | char *s1, *s2; | |
82 | ||
83 | if (n == 0) | |
84 | { | |
85 | s1 = (char*)(buf1 + page_size); | |
86 | s2 = (char*)(buf2 + page_size); | |
87 | if (HP_TIMING_AVAIL) | |
88 | printf ("Length %4zd/%4zd:", len, n); | |
89 | ||
90 | FOR_EACH_IMPL (impl, 0) | |
91 | do_one_test (impl, s1, s2, n, 0); | |
92 | ||
93 | if (HP_TIMING_AVAIL) | |
94 | putchar ('\n'); | |
95 | ||
96 | return; | |
97 | } | |
98 | ||
99 | align1 &= 15; | |
100 | align2 &= 15; | |
101 | align_n = (page_size - n) & 15; | |
102 | ||
103 | s1 = (char*)(buf1 + page_size - n); | |
104 | s2 = (char*)(buf2 + page_size - n); | |
105 | ||
106 | if (align1 < align_n) | |
107 | s1 -= (align_n - align1); | |
108 | ||
109 | if (align2 < align_n) | |
110 | s2 -= (align_n - align2); | |
111 | ||
112 | for (i = 0; i < n; i++) | |
113 | s1[i] = s2[i] = 1 + 23 * i % max_char; | |
114 | ||
115 | if (len < n) | |
116 | { | |
117 | s1[len] = 0; | |
118 | s2[len] = 0; | |
119 | if (exp_result < 0) | |
120 | s2[len] = 32; | |
121 | else if (exp_result > 0) | |
122 | s1[len] = 64; | |
123 | } | |
124 | ||
125 | if (HP_TIMING_AVAIL) | |
126 | printf ("Length %4zd/%4zd, alignment %2zd/%2zd:", len, n, align1, align2); | |
127 | ||
128 | FOR_EACH_IMPL (impl, 0) | |
129 | do_one_test (impl, s1, s2, n, exp_result); | |
130 | ||
131 | if (HP_TIMING_AVAIL) | |
132 | putchar ('\n'); | |
133 | } | |
134 | ||
135 | static void | |
136 | do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char, | |
137 | int exp_result) | |
138 | { | |
139 | size_t i; | |
140 | char *s1, *s2; | |
141 | ||
142 | if (n == 0) | |
143 | return; | |
144 | ||
145 | align1 &= 7; | |
146 | if (align1 + n + 1 >= page_size) | |
147 | return; | |
148 | ||
149 | align2 &= 7; | |
150 | if (align2 + n + 1 >= page_size) | |
151 | return; | |
152 | ||
153 | s1 = (char*)(buf1 + align1); | |
154 | s2 = (char*)(buf2 + align2); | |
155 | ||
156 | for (i = 0; i < n; i++) | |
157 | s1[i] = s2[i] = 1 + 23 * i % max_char; | |
158 | ||
159 | s1[n] = 24 + exp_result; | |
160 | s2[n] = 23; | |
161 | s1[len] = 0; | |
162 | s2[len] = 0; | |
163 | if (exp_result < 0) | |
164 | s2[len] = 32; | |
165 | else if (exp_result > 0) | |
166 | s1[len] = 64; | |
167 | if (len >= n) | |
168 | s2[n - 1] -= exp_result; | |
169 | ||
170 | if (HP_TIMING_AVAIL) | |
171 | printf ("Length %4zd/%4zd, alignment %2zd/%2zd:", len, n, align1, align2); | |
172 | ||
173 | FOR_EACH_IMPL (impl, 0) | |
174 | do_one_test (impl, (char*)s1, (char*)s2, n, exp_result); | |
175 | ||
176 | if (HP_TIMING_AVAIL) | |
177 | putchar ('\n'); | |
178 | } | |
179 | ||
180 | int | |
181 | test_main (void) | |
182 | { | |
183 | size_t i; | |
184 | ||
185 | test_init (); | |
186 | ||
187 | printf ("%23s", ""); | |
188 | FOR_EACH_IMPL (impl, 0) | |
189 | printf ("\t%s", impl->name); | |
190 | putchar ('\n'); | |
191 | ||
192 | for (i =0; i < 16; ++i) | |
193 | { | |
194 | do_test (0, 0, 8, i, 127, 0); | |
195 | do_test (0, 0, 8, i, 127, -1); | |
196 | do_test (0, 0, 8, i, 127, 1); | |
197 | do_test (i, i, 8, i, 127, 0); | |
198 | do_test (i, i, 8, i, 127, 1); | |
199 | do_test (i, i, 8, i, 127, -1); | |
200 | do_test (i, 2 * i, 8, i, 127, 0); | |
201 | do_test (2 * i, i, 8, i, 127, 1); | |
202 | do_test (i, 3 * i, 8, i, 127, -1); | |
203 | do_test (0, 0, 8, i, 255, 0); | |
204 | do_test (0, 0, 8, i, 255, -1); | |
205 | do_test (0, 0, 8, i, 255, 1); | |
206 | do_test (i, i, 8, i, 255, 0); | |
207 | do_test (i, i, 8, i, 255, 1); | |
208 | do_test (i, i, 8, i, 255, -1); | |
209 | do_test (i, 2 * i, 8, i, 255, 0); | |
210 | do_test (2 * i, i, 8, i, 255, 1); | |
211 | do_test (i, 3 * i, 8, i, 255, -1); | |
212 | } | |
213 | ||
214 | for (i = 1; i < 8; ++i) | |
215 | { | |
216 | do_test (0, 0, 8 << i, 16 << i, 127, 0); | |
217 | do_test (0, 0, 8 << i, 16 << i, 127, 1); | |
218 | do_test (0, 0, 8 << i, 16 << i, 127, -1); | |
219 | do_test (0, 0, 8 << i, 16 << i, 255, 0); | |
220 | do_test (0, 0, 8 << i, 16 << i, 255, 1); | |
221 | do_test (0, 0, 8 << i, 16 << i, 255, -1); | |
222 | do_test (8 - i, 2 * i, 8 << i, 16 << i, 127, 0); | |
223 | do_test (8 - i, 2 * i, 8 << i, 16 << i, 127, 1); | |
224 | do_test (2 * i, i, 8 << i, 16 << i, 255, 0); | |
225 | do_test (2 * i, i, 8 << i, 16 << i, 255, 1); | |
226 | } | |
227 | ||
228 | do_test_limit (0, 0, 0, 0, 127, 0); | |
229 | do_test_limit (4, 0, 21, 20, 127, 0); | |
230 | do_test_limit (0, 4, 21, 20, 127, 0); | |
231 | do_test_limit (8, 0, 25, 24, 127, 0); | |
232 | do_test_limit (0, 8, 25, 24, 127, 0); | |
233 | ||
234 | for (i = 0; i < 8; ++i) | |
235 | { | |
236 | do_test_limit (0, 0, 17 - i, 16 - i, 127, 0); | |
237 | do_test_limit (0, 0, 17 - i, 16 - i, 255, 0); | |
238 | do_test_limit (0, 0, 15 - i, 16 - i, 127, 0); | |
239 | do_test_limit (0, 0, 15 - i, 16 - i, 127, 1); | |
240 | do_test_limit (0, 0, 15 - i, 16 - i, 127, -1); | |
241 | do_test_limit (0, 0, 15 - i, 16 - i, 255, 0); | |
242 | do_test_limit (0, 0, 15 - i, 16 - i, 255, 1); | |
243 | do_test_limit (0, 0, 15 - i, 16 - i, 255, -1); | |
244 | } | |
245 | ||
246 | return ret; | |
247 | } | |
248 | ||
249 | #include "../test-skeleton.c" |