Skip to content

Commit a62f9d1

Browse files
garimasi514dscho
authored andcommitted
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 <[email protected]> Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 525e7fb commit a62f9d1

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed

t/helper/test-path-utils.c

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,99 @@ static int is_dotgitmodules(const char *path)
176176
return is_hfs_dotgitmodules(path) || is_ntfs_dotgitmodules(path);
177177
}
178178

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+
179272
int cmd_main(int argc, const char **argv)
180273
{
181274
if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) {
@@ -290,6 +383,9 @@ int cmd_main(int argc, const char **argv)
290383
return !!res;
291384
}
292385

386+
if (argc > 1 && !strcmp(argv[1], "protect_ntfs_hfs"))
387+
return !!protect_ntfs_hfs_benchmark(argc - 1, argv + 1);
388+
293389
fprintf(stderr, "%s: unknown function name: %s\n", argv[0],
294390
argv[1] ? argv[1] : "(there was none)");
295391
return 1;

0 commit comments

Comments
 (0)