@matheusbsbs / matheus-bagliano / commits / a62f9d1ace
Fork 0

test-path-utils: offer to run a protectNTFS/protectHFS benchmark

In preparation to flipping the default on `core.protectNTFS`, let's have some way to measure the speed impact of this config setting reliably (and for comparison, the `core.protectHFS` config setting). For now, this is a manual performance benchmark: ./t/helper/test-path-utils protect_ntfs_hfs [arguments...] where the arguments are an optional number of file names to test with, optionally followed by minimum and maximum length of the random file names. The default values are one million, 3 and 20, respectively. Just like `sqrti()` in `bisect.c`, we introduce a very simple function to approximation the square root of a given value, in order to avoid having to introduce the first user of `<math.h>` in Git's source code. Note: this is _not_ implemented as a Unix shell script in t/perf/ because we really care about _very_ precise timings here, and Unix shell scripts are simply unsuited for precise and consistent benchmarking. Signed-off-by: Garima Singh <garima.singh@microsoft.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>

Garima Singh committed Sep 4, 2019 at 13:36 UTC a62f9d1ace8c6556cbc1bb7df69eff0a0bb9e774
1 file changed +96
t/helper/test-path-utils.c
+96
@@ -176,6 +176,99 @@ static int is_dotgitmodules(const char *path)
176 return is_hfs_dotgitmodules(path) || is_ntfs_dotgitmodules(path);
177 }
178
179 +/*
180 + * A very simple, reproducible pseudo-random generator. Copied from
181 + * `test-genrandom.c`.
182 + */
183 +static uint64_t my_random_value = 1234;
184 +
185 +static uint64_t my_random(void)
186 +{
187 + my_random_value = my_random_value * 1103515245 + 12345;
188 + return my_random_value;
189 +}
190 +
191 +/*
192 + * A fast approximation of the square root, without requiring math.h.
193 + *
194 + * It uses Newton's method to approximate the solution of 0 = x^2 - value.
195 + */
196 +static double my_sqrt(double value)
197 +{
198 + const double epsilon = 1e-6;
199 + double x = value;
200 +
201 + if (value == 0)
202 + return 0;
203 +
204 + for (;;) {
205 + double delta = (value / x - x) / 2;
206 + if (delta < epsilon && delta > -epsilon)
207 + return x + delta;
208 + x += delta;
209 + }
210 +}
211 +
212 +static int protect_ntfs_hfs_benchmark(int argc, const char **argv)
213 +{
214 + size_t i, j, nr, min_len = 3, max_len = 20;
215 + char **names;
216 + int repetitions = 15, file_mode = 0100644;
217 + uint64_t begin, end;
218 + double m[3][2], v[3][2];
219 + uint64_t cumul;
220 + double cumul2;
221 +
222 + if (argc > 1 && !strcmp(argv[1], "--with-symlink-mode")) {
223 + file_mode = 0120000;
224 + argc--;
225 + argv++;
226 + }
227 +
228 + nr = argc > 1 ? strtoul(argv[1], NULL, 0) : 1000000;
229 + ALLOC_ARRAY(names, nr);
230 +
231 + if (argc > 2) {
232 + min_len = strtoul(argv[2], NULL, 0);
233 + if (argc > 3)
234 + max_len = strtoul(argv[3], NULL, 0);
235 + if (min_len > max_len)
236 + die("min_len > max_len");
237 + }
238 +
239 + for (i = 0; i < nr; i++) {
240 + size_t len = min_len + (my_random() % (max_len + 1 - min_len));
241 +
242 + names[i] = xmallocz(len);
243 + while (len > 0)
244 + names[i][--len] = (char)(' ' + (my_random() % ('\x7f' - ' ')));
245 + }
246 +
247 + for (protect_ntfs = 0; protect_ntfs < 2; protect_ntfs++)
248 + for (protect_hfs = 0; protect_hfs < 2; protect_hfs++) {
249 + cumul = 0;
250 + cumul2 = 0;
251 + for (i = 0; i < repetitions; i++) {
252 + begin = getnanotime();
253 + for (j = 0; j < nr; j++)
254 + verify_path(names[j], file_mode);
255 + end = getnanotime();
256 + printf("protect_ntfs = %d, protect_hfs = %d: %lfms\n", protect_ntfs, protect_hfs, (end-begin) / (double)1e6);
257 + cumul += end - begin;
258 + cumul2 += (end - begin) * (end - begin);
259 + }
260 + m[protect_ntfs][protect_hfs] = cumul / (double)repetitions;
261 + v[protect_ntfs][protect_hfs] = my_sqrt(cumul2 / (double)repetitions - m[protect_ntfs][protect_hfs] * m[protect_ntfs][protect_hfs]);
262 + printf("mean: %lfms, stddev: %lfms\n", m[protect_ntfs][protect_hfs] / (double)1e6, v[protect_ntfs][protect_hfs] / (double)1e6);
263 + }
264 +
265 + for (protect_ntfs = 0; protect_ntfs < 2; protect_ntfs++)
266 + for (protect_hfs = 0; protect_hfs < 2; protect_hfs++)
267 + printf("ntfs=%d/hfs=%d: %lf%% slower\n", protect_ntfs, protect_hfs, (m[protect_ntfs][protect_hfs] - m[0][0]) * 100 / m[0][0]);
268 +
269 + return 0;
270 +}
271 +
272 int cmd_main(int argc, const char **argv)
273 {
274 if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) {
@@ -290,6 +383,9 @@ int cmd_main(int argc, const char **argv)
383 return !!res;
384 }
385
386 + if (argc > 1 && !strcmp(argv[1], "protect_ntfs_hfs"))
387 + return !!protect_ntfs_hfs_benchmark(argc - 1, argv + 1);
388 +
389 fprintf(stderr, "%s: unknown function name: %s\n", argv[0],
390 argv[1] ? argv[1] : "(there was none)");
391 return 1;