Skip to content

Commit 79ed0a5

Browse files
peffgitster
authored andcommitted
cat-file: use a single strbuf for all output
When we're in batch mode, we end up in batch_object_write() for each object, which allocates its own strbuf for each call. Instead, we can provide a single "scratch" buffer that gets reused for each output. When running: git cat-file --batch-all-objects --batch-check='%(objectname)' on git.git, my best-of-five time drops from: real 0m0.171s user 0m0.159s sys 0m0.012s to: real 0m0.133s user 0m0.121s sys 0m0.012s Note that we could do this just by putting the "scratch" pointer into "struct expand_data", but I chose instead to add an extra parameter to the callstack. That's more verbose, but it makes it a bit more obvious what is going on, which in turn makes it easy to see where we need to be releasing the string in the caller (right after the loop which uses it in each case). Based-on-a-patch-by: René Scharfe <[email protected]> Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 54d2f0d commit 79ed0a5

File tree

1 file changed

+17
-11
lines changed

1 file changed

+17
-11
lines changed

builtin/cat-file.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -338,11 +338,11 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d
338338
}
339339
}
340340

341-
static void batch_object_write(const char *obj_name, struct batch_options *opt,
341+
static void batch_object_write(const char *obj_name,
342+
struct strbuf *scratch,
343+
struct batch_options *opt,
342344
struct expand_data *data)
343345
{
344-
struct strbuf buf = STRBUF_INIT;
345-
346346
if (!data->skip_object_info &&
347347
oid_object_info_extended(the_repository, &data->oid, &data->info,
348348
OBJECT_INFO_LOOKUP_REPLACE) < 0) {
@@ -352,18 +352,20 @@ static void batch_object_write(const char *obj_name, struct batch_options *opt,
352352
return;
353353
}
354354

355-
strbuf_expand(&buf, opt->format, expand_format, data);
356-
strbuf_addch(&buf, '\n');
357-
batch_write(opt, buf.buf, buf.len);
358-
strbuf_release(&buf);
355+
strbuf_reset(scratch);
356+
strbuf_expand(scratch, opt->format, expand_format, data);
357+
strbuf_addch(scratch, '\n');
358+
batch_write(opt, scratch->buf, scratch->len);
359359

360360
if (opt->print_contents) {
361361
print_object_or_die(opt, data);
362362
batch_write(opt, "\n", 1);
363363
}
364364
}
365365

366-
static void batch_one_object(const char *obj_name, struct batch_options *opt,
366+
static void batch_one_object(const char *obj_name,
367+
struct strbuf *scratch,
368+
struct batch_options *opt,
367369
struct expand_data *data)
368370
{
369371
struct object_context ctx;
@@ -405,20 +407,21 @@ static void batch_one_object(const char *obj_name, struct batch_options *opt,
405407
return;
406408
}
407409

408-
batch_object_write(obj_name, opt, data);
410+
batch_object_write(obj_name, scratch, opt, data);
409411
}
410412

411413
struct object_cb_data {
412414
struct batch_options *opt;
413415
struct expand_data *expand;
414416
struct oidset *seen;
417+
struct strbuf *scratch;
415418
};
416419

417420
static int batch_object_cb(const struct object_id *oid, void *vdata)
418421
{
419422
struct object_cb_data *data = vdata;
420423
oidcpy(&data->expand->oid, oid);
421-
batch_object_write(NULL, data->opt, data->expand);
424+
batch_object_write(NULL, data->scratch, data->opt, data->expand);
422425
return 0;
423426
}
424427

@@ -509,6 +512,7 @@ static int batch_objects(struct batch_options *opt)
509512

510513
cb.opt = opt;
511514
cb.expand = &data;
515+
cb.scratch = &output;
512516

513517
if (opt->unordered) {
514518
struct oidset seen = OIDSET_INIT;
@@ -531,6 +535,7 @@ static int batch_objects(struct batch_options *opt)
531535
oid_array_clear(&sa);
532536
}
533537

538+
strbuf_release(&output);
534539
return 0;
535540
}
536541

@@ -559,10 +564,11 @@ static int batch_objects(struct batch_options *opt)
559564
data.rest = p;
560565
}
561566

562-
batch_one_object(input.buf, opt, &data);
567+
batch_one_object(input.buf, &output, opt, &data);
563568
}
564569

565570
strbuf_release(&input);
571+
strbuf_release(&output);
566572
warn_on_object_refname_ambiguity = save_warning;
567573
return retval;
568574
}

0 commit comments

Comments
 (0)