Skip to content

Commit eb54a33

Browse files
john-caigitster
authored andcommitted
cat-file: skip expanding default format
When format is passed into --batch, --batch-check, --batch-command, the format gets expanded. When nothing is passed in, the default format is set and the expand_format() gets called. We can save on these cycles by hardcoding how to print the information when nothing is passed as the format, or when the default format is passed. There is no need for the fully expanded format with the default. Since batch_object_write() happens on every object provided in batch mode, we get a nice performance improvement. git rev-list --all > /tmp/all-obj.txt git cat-file --batch-check </tmp/all-obj.txt with HEAD^: Time (mean ± σ): 57.6 ms ± 1.7 ms [User: 51.5 ms, System: 6.2 ms] Range (min … max): 54.6 ms … 64.7 ms 50 runs with HEAD: Time (mean ± σ): 49.8 ms ± 1.7 ms [User: 42.6 ms, System: 7.3 ms] Range (min … max): 46.9 ms … 55.9 ms 56 runs If nothing is provided as a format argument, or if the default format is passed, skip expanding of the format and print the object info with a default format. See https://lore.kernel.org/git/[email protected]/ Signed-off-by: Ævar Arnfjörð Bjarmason <[email protected]> Signed-off-by: John Cai <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c216290 commit eb54a33

File tree

2 files changed

+35
-6
lines changed

2 files changed

+35
-6
lines changed

builtin/cat-file.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,13 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d
351351
}
352352
}
353353

354+
static void print_default_format(struct strbuf *scratch, struct expand_data *data)
355+
{
356+
strbuf_addf(scratch, "%s %s %"PRIuMAX"\n", oid_to_hex(&data->oid),
357+
type_name(data->type),
358+
(uintmax_t)data->size);
359+
}
360+
354361
/*
355362
* If "pack" is non-NULL, then "offset" is the byte offset within the pack from
356363
* which the object may be accessed (though note that we may also rely on
@@ -382,8 +389,14 @@ static void batch_object_write(const char *obj_name,
382389
}
383390

384391
strbuf_reset(scratch);
385-
strbuf_expand(scratch, opt->format, expand_format, data);
386-
strbuf_addch(scratch, '\n');
392+
393+
if (!opt->format) {
394+
print_default_format(scratch, data);
395+
} else {
396+
strbuf_expand(scratch, opt->format, expand_format, data);
397+
strbuf_addch(scratch, '\n');
398+
}
399+
387400
batch_write(opt, scratch->buf, scratch->len);
388401

389402
if (opt->print_contents) {
@@ -508,6 +521,8 @@ static int batch_unordered_packed(const struct object_id *oid,
508521
data);
509522
}
510523

524+
#define DEFAULT_FORMAT "%(objectname) %(objecttype) %(objectsize)"
525+
511526
static int batch_objects(struct batch_options *opt)
512527
{
513528
struct strbuf input = STRBUF_INIT;
@@ -516,22 +531,24 @@ static int batch_objects(struct batch_options *opt)
516531
int save_warning;
517532
int retval = 0;
518533

519-
if (!opt->format)
520-
opt->format = "%(objectname) %(objecttype) %(objectsize)";
521-
522534
/*
523535
* Expand once with our special mark_query flag, which will prime the
524536
* object_info to be handed to oid_object_info_extended for each
525537
* object.
526538
*/
527539
memset(&data, 0, sizeof(data));
528540
data.mark_query = 1;
529-
strbuf_expand(&output, opt->format, expand_format, &data);
541+
strbuf_expand(&output,
542+
opt->format ? opt->format : DEFAULT_FORMAT,
543+
expand_format,
544+
&data);
530545
data.mark_query = 0;
531546
strbuf_release(&output);
532547
if (opt->cmdmode)
533548
data.split_on_whitespace = 1;
534549

550+
if (opt->format && !strcmp(opt->format, DEFAULT_FORMAT))
551+
opt->format = NULL;
535552
/*
536553
* If we are printing out the object, then always fill in the type,
537554
* since we will want to decide whether or not to stream.

t/perf/p1006-cat-file.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/bin/sh
2+
3+
test_description='Tests listing object info performance'
4+
. ./perf-lib.sh
5+
6+
test_perf_large_repo
7+
8+
test_perf 'cat-file --batch-check' '
9+
git cat-file --batch-all-objects --batch-check
10+
'
11+
12+
test_done

0 commit comments

Comments
 (0)