1 /* This file tests how efficient differrent lengths of _BUF nodes are and also
2 * compares them to one big pile
3 * -- vstr is kind of built on the idea that this isn't a problem for
4 * reasonable sizes */
5
6 #define VSTR_COMPILE_INCLUDE 1
7
8 #include <vstr.h>
9
10 #if 0
11 # define TST_SZ_BEG (64 - (16 + 8))
12 # define TST_SZ_INC ((sz == (64 - (16 + 8))) ? (16 + 8) : \
13 (sz == 64) ? (64 - (16 + 8)) : \
14 (sz == (128 - (16 + 8))) ? (16 + 8) : \
15 (sz == 128) ? (128 - (16 + 8)) : \
16 (sz == (256 - (16 + 8))) ? (16 + 8) : \
17 (sz == 256) ? (256 - (16 + 8)) : \
18 (sz == (512 - (16 + 8))) ? (16 + 8) : \
19 (sz == 512) ? (512 - (16 + 8)) : \
20 (sz == (1024 - (16 + 8))) ? (16 + 8) : \
21 (sz == 1024) ? (3072 - (16 + 8)) : \
22 (sz == (4096 - (16 + 8))) ? (16 + 8) : 1)
23 # define TST_SZ_END (4096)
24 #else
25 # define TST_SZ_BEG (512 - (16 + 8))
26 # define TST_SZ_INC ((sz == (512 - (16 + 8))) ? (16 + 8) : \
27 (sz == 512) ? (512 + 3072 - (16 + 8)) : \
28 (sz == (4096 - (16 + 8))) ? (16 + 8) : 1)
29 # define TST_SZ_END (4096)
30 #endif
31
32 /* #define TST_SZ_END (4096 - (sizeof(Vstr_node) + 16)) */
33
34 /*
35 #define TST_NUM_BEG (64)
36 #define TST_NUM_END (1024)
37 */
38 #define TST_NUM_BEG (4096)
39 #define TST_NUM_INC (1)
40 #define TST_NUM_END (4096)
41
42 #define TST_LEN_BEG (sz >= 128 ? 128 : 1)
43 #define TST_LEN_INC (1)
44 #define TST_LEN_END (1024 * 100)
45
46 #define TST_MALLOC_EXTRA_BEG (0)
47 #define TST_MALLOC_EXTRA_INC (1024)
48 #define TST_MALLOC_EXTRA_END (1024 * 2)
49
50 #define TST_COUNT_BEG (1)
51 #define TST_COUNT_INC (1)
52 #define TST_COUNT_END (2)
53
54 #define TST_USE_MEMCPY 1
55
56 #include "ex_perf.h"
57
58 #include <assert.h>
59 #include <unistd.h>
60
61 #include <glib.h>
62
63
64 /* this is M_TRIM_THRESH */
65 #define TST_ALLOC_TRIM() do { \
66 struct mallinfo mal_info = mallinfo(); \
67 trig_trim = malloc((128 * 1024) + mal_info.fordblks); \
68 if (!trig_trim) goto failed; \
69 } while (0)
70
71 #define TST_CLEANUP_TRIM(x) do { \
72 unsigned int clean_extra = num; \
73 \
74 if (extra) \
75 while (clean_extra--) \
76 free(mal_overhead[clean_extra]); \
77 \
78 if (x) free(trig_trim); \
79 } while (0)
80
81
main(void)82 int main(void)
83 {
84 Vstr_conf *conf = NULL;
85 Vstr_base *out = NULL;
86 Vstr_base *s1 = NULL;
87 char *s2 = NULL;
88 GString *s3 = NULL;
89 char *s4 = NULL;
90 unsigned int ern = 0;
91 char *mal_overhead[TST_NUM_END];
92 char *s3_data = NULL;
93
94 mallopt(M_MMAP_MAX, 0); /* mmap() can change the results */
95
96 if (!vstr_init())
97 exit(EXIT_FAILURE);
98
99 conf = vstr_make_conf();
100 if (!conf)
101 exit(EXIT_FAILURE);
102
103 out = vstr_make_base(NULL); /* used as stdio/stdout */
104 if (!out)
105 exit (EXIT_FAILURE);
106
107 s3_data = malloc(TST_LEN_END);
108 if (!s3_data)
109 goto failed;
110 memset(s3_data, 'x', TST_LEN_END);
111
112 vstr_cntl_conf(NULL, VSTR_CNTL_CONF_SET_NUM_RANGE_SPARE_BUF, 128, 128);
113
114 if (1)
115 {
116 unsigned int sz = TST_SZ_BEG;
117 while (sz <= TST_SZ_END)
118 {
119 unsigned int len = TST_LEN_BEG;
120
121 vstr_free_base(s1);
122 vstr_cntl_conf(conf, VSTR_CNTL_CONF_SET_NUM_BUF_SZ, sz);
123 s1 = vstr_make_base(conf);
124 if (!s1)
125 goto failed;
126
127 while (len <= TST_LEN_END)
128 {
129 unsigned int num = TST_NUM_BEG;
130 while (num <= TST_NUM_END)
131 {
132 unsigned int extra = TST_MALLOC_EXTRA_BEG;
133 while (extra <= TST_MALLOC_EXTRA_END)
134 {
135 unsigned int count = TST_COUNT_BEG;
136 while (count <= TST_COUNT_END)
137 {
138 void *trig_trim = NULL;
139
140 TST_ALLOC_TRIM();
141
142 TST_BEG(1, num);
143 if (extra)
144 mal_overhead[tst_count] = malloc(extra);
145 buf_out[0] = 'x';
146 if (TST_USE_MEMCPY)
147 vstr_add_buf(s1, s1->len, s3_data, len);
148 else
149 vstr_add_rep_chr(s1, s1->len, buf_out[0], len);
150 TST_CALC_END("V");
151
152 vstr_del(s1, 1, s1->len);
153 TST_CLEANUP_TRIM(0);
154
155 TST_BEG(1, num);
156 if (extra)
157 mal_overhead[tst_count] = malloc(extra);
158 buf_out[0] = 'x';
159 if (TST_USE_MEMCPY)
160 vstr_add_buf(s1, s1->len, s3_data, len);
161 else
162 vstr_add_rep_chr(s1, s1->len, buf_out[0], len);
163 TST_CALC_END("A");
164
165 vstr_del(s1, 1, s1->len);
166 vstr_cntl_conf(conf, VSTR_CNTL_CONF_SET_NUM_RANGE_SPARE_BUF, 0, 0);
167 TST_CLEANUP_TRIM(1);
168 TST_ALLOC_TRIM();
169
170 s2 = malloc(sz); /* single object */
171 if (!s2)
172 goto failed;
173
174 TST_BEG(1, num);
175 unsigned int off = (len * tst_count);
176 unsigned int new_len = off + len;
177 if (extra)
178 mal_overhead[tst_count] = malloc(extra);
179 buf_out[0] = 'x';
180 s2 = realloc(s2, new_len);
181 if (!s2)
182 goto failed;
183 if (TST_USE_MEMCPY)
184 memcpy(s2 + off, s3_data, len);
185 else
186 memset(s2 + off, buf_out[0], len);
187 TST_CALC_END("S");
188
189 free(s2);
190 s2 = NULL;
191 TST_CLEANUP_TRIM(1);
192 TST_ALLOC_TRIM();
193
194 if (TST_USE_MEMCPY)
195 {
196 s3 = g_string_sized_new(sz);
197 TST_BEG(1, num);
198 if (extra)
199 mal_overhead[tst_count] = malloc(extra);
200 buf_out[0] = 'x';
201 g_string_append_len(s3, s3_data, len);
202 TST_CALC_END("G");
203
204 g_string_free(s3, TRUE);
205 s3 = NULL;
206 TST_CLEANUP_TRIM(1);
207 TST_ALLOC_TRIM();
208
209 TST_BEG(1, num);
210 if (extra)
211 mal_overhead[tst_count] = malloc(extra);
212 buf_out[0] = 'x';
213 vstr_add_ptr(s1, s1->len, s3_data, len);
214 TST_CALC_END("P");
215
216 vstr_del(s1, 1, s1->len);
217 vstr_cntl_conf(conf, VSTR_CNTL_CONF_SET_NUM_RANGE_SPARE_PTR, 0, 0);
218 TST_CLEANUP_TRIM(1);
219 TST_ALLOC_TRIM();
220 }
221
222 s4 = malloc(len); /* single object */
223 if (!s4)
224 goto failed;
225
226 TST_BEG(1, num);
227 if (extra)
228 mal_overhead[tst_count] = malloc(extra);
229 buf_out[0] = 'x';
230 if (TST_USE_MEMCPY)
231 memcpy(s4, s3_data, len);
232 else
233 memset(s4, buf_out[0], len);
234 TST_CALC_END("B");
235
236 free(s4);
237 s4 = NULL;
238 TST_CLEANUP_TRIM(1);
239
240 if (out->len)
241 vstr_sc_write_fd(out, 1, out->len, 1 /* stdout */, &ern);
242 if (ern)
243 goto failed;
244
245 count += TST_COUNT_INC;
246 }
247 extra += TST_MALLOC_EXTRA_INC;
248 }
249 num += TST_NUM_INC;
250 }
251 len += TST_LEN_INC;
252 }
253 sz += TST_SZ_INC;
254 }
255 }
256
257 if (s1->conf->malloc_bad || out->conf->malloc_bad)
258 goto failed;
259
260 while (out->len && !ern)
261 vstr_sc_write_fd(out, 1, out->len, STDOUT_FILENO, &ern);
262
263 vstr_free_conf(conf);
264 vstr_free_base(out);
265 vstr_free_base(s1);
266 free(s2);
267
268 vstr_exit();
269
270 exit (EXIT_SUCCESS);
271
272 failed:
273 ern = 0;
274 while (out->len && !ern)
275 vstr_sc_write_fd(out, 1, out->len, STDERR_FILENO, &ern);
276
277 vstr_free_base(out);
278 vstr_free_base(s1);
279 free(s2);
280
281 vstr_exit();
282
283 exit (EXIT_FAILURE);
284 }
285
286