Skip to content

Commit a8032d1

Browse files
Nicolas Pitregitster
authored andcommitted
sha1write: don't copy full sized buffers
No need to memcpy() source buffer data when we might just process the data in place instead of accumulating it into a separate buffer. This is the case when a whole buffer would have been copied, summed, written out and then discarded right away. Also move the CRC32 processing within the loop so the data is more likely to remain in the L1 CPU cache between the CRC32 sum, SHA1 sum and the write call. Signed-off-by: Nicolas Pitre <nico@cam.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 59d94bc commit a8032d1

File tree

1 file changed

+17
-10
lines changed

1 file changed

+17
-10
lines changed

csum-file.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,8 @@
1111
#include "progress.h"
1212
#include "csum-file.h"
1313

14-
static void sha1flush(struct sha1file *f, unsigned int count)
14+
static void sha1flush(struct sha1file *f, void *buf, unsigned int count)
1515
{
16-
void *buf = f->buffer;
17-
1816
for (;;) {
1917
int ret = xwrite(f->fd, buf, count);
2018
if (ret > 0) {
@@ -39,15 +37,15 @@ int sha1close(struct sha1file *f, unsigned char *result, unsigned int flags)
3937

4038
if (offset) {
4139
SHA1_Update(&f->ctx, f->buffer, offset);
42-
sha1flush(f, offset);
40+
sha1flush(f, f->buffer, offset);
4341
f->offset = 0;
4442
}
4543
SHA1_Final(f->buffer, &f->ctx);
4644
if (result)
4745
hashcpy(result, f->buffer);
4846
if (flags & (CSUM_CLOSE | CSUM_FSYNC)) {
4947
/* write checksum and close fd */
50-
sha1flush(f, 20);
48+
sha1flush(f, f->buffer, 20);
5149
if (flags & CSUM_FSYNC)
5250
fsync_or_die(f->fd, f->name);
5351
if (close(f->fd))
@@ -62,21 +60,30 @@ int sha1close(struct sha1file *f, unsigned char *result, unsigned int flags)
6260

6361
int sha1write(struct sha1file *f, void *buf, unsigned int count)
6462
{
65-
if (f->do_crc)
66-
f->crc32 = crc32(f->crc32, buf, count);
6763
while (count) {
6864
unsigned offset = f->offset;
6965
unsigned left = sizeof(f->buffer) - offset;
7066
unsigned nr = count > left ? left : count;
67+
void *data;
68+
69+
if (f->do_crc)
70+
f->crc32 = crc32(f->crc32, buf, nr);
71+
72+
if (nr == sizeof(f->buffer)) {
73+
/* process full buffer directly without copy */
74+
data = buf;
75+
} else {
76+
memcpy(f->buffer + offset, buf, nr);
77+
data = f->buffer;
78+
}
7179

72-
memcpy(f->buffer + offset, buf, nr);
7380
count -= nr;
7481
offset += nr;
7582
buf = (char *) buf + nr;
7683
left -= nr;
7784
if (!left) {
78-
SHA1_Update(&f->ctx, f->buffer, offset);
79-
sha1flush(f, offset);
85+
SHA1_Update(&f->ctx, data, offset);
86+
sha1flush(f, data, offset);
8087
offset = 0;
8188
}
8289
f->offset = offset;

0 commit comments

Comments
 (0)