diff options
author | Robin Watts <robin.watts@artifex.com> | 2016-02-11 16:00:36 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2016-02-12 16:52:52 +0000 |
commit | 4b6c0ab659b3feb5f8e3683e393d61ccfdc09c3c (patch) | |
tree | 7c2210beb8858171e8f72388444c06d69ebf383e /source | |
parent | 16e82693f89d2b1d176fb7b2f5718d5270ad0239 (diff) | |
download | mupdf-4b6c0ab659b3feb5f8e3683e393d61ccfdc09c3c.tar.xz |
Bug 696580: Speed up fz_write_pnm_band.
Writing individual bytes using fwrite is VERY slow (profile of debug
code shows 93% of runtime is in system fwrite). Fix this by collating
into a buffer and writing (now 2.5%).
Diffstat (limited to 'source')
-rw-r--r-- | source/fitz/pixmap.c | 61 |
1 files changed, 46 insertions, 15 deletions
diff --git a/source/fitz/pixmap.c b/source/fitz/pixmap.c index d2086d6f..8bdb5cb9 100644 --- a/source/fitz/pixmap.c +++ b/source/fitz/pixmap.c @@ -582,6 +582,7 @@ fz_write_pnm_header(fz_context *ctx, fz_output *out, int w, int h, int n) void fz_write_pnm_band(fz_context *ctx, fz_output *out, int w, int h, int n, int band, int bandheight, unsigned char *p) { + char buffer[2*3*4*5*6]; /* Buffer must be a multiple of 2 and 3 at least. */ int len; int start = band * bandheight; int end = start + bandheight; @@ -592,26 +593,56 @@ fz_write_pnm_band(fz_context *ctx, fz_output *out, int w, int h, int n, int band len = w * end; - switch (n) + /* Tests show that writing single bytes out at a time + * is appallingly slow. We get a huge improvement + * by collating stuff into buffers first. */ + + while (len) { - case 1: - fz_write(ctx, out, p, len); - break; - case 2: - while (len--) + int num_written = len; + + switch (n) + { + case 1: + /* No collation required */ + fz_write(ctx, out, p, num_written); + break; + case 2: { - fz_putc(ctx, out, p[0]); - p += 2; + char *o = buffer; + int count; + + if (num_written > sizeof(buffer)) + num_written = sizeof(buffer); + + for (count = num_written; count; count--) + { + *o++ = *p; + p += 2; + } + fz_write(ctx, out, buffer, num_written); + break; } - break; - case 4: - while (len--) + case 4: { - fz_putc(ctx, out, p[0]); - fz_putc(ctx, out, p[1]); - fz_putc(ctx, out, p[2]); - p += 4; + char *o = buffer; + int count; + + if (num_written > sizeof(buffer)/3) + num_written = sizeof(buffer)/3; + + for (count = num_written; count; count--) + { + *o++ = p[0]; + *o++ = p[1]; + *o++ = p[2]; + p += 4; + } + fz_write(ctx, out, buffer, num_written * 3); + break; + } } + len -= num_written; } } |