diff options
author | Steve Bennett <steveb@workware.net.au> | 2023-01-31 16:51:41 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2023-01-31 16:53:23 +1000 |
commit | e44134667c52674c0b9bfdab303dc8ddc1c933b8 (patch) | |
tree | b2c2233f4d48ccfa4036be3261cad8991268aaad | |
parent | 5a09d43250a51c2dc3c76dfebf5184c75b1c410e (diff) | |
download | jimtcl-e44134667c52674c0b9bfdab303dc8ddc1c933b8.zip jimtcl-e44134667c52674c0b9bfdab303dc8ddc1c933b8.tar.gz jimtcl-e44134667c52674c0b9bfdab303dc8ddc1c933b8.tar.bz2 |
aio copyto: improve performance for large copies
Rather than continuing to use a small buffer for large copies,
if the size exceeds a certain threshold (currently 16kB) switch
to a larger, allocated buffer (currently 64kB).
This should speed up large copies without penalising small copies.
Note that these are simply heuristics and may not be appropriate
on all systems.
Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r-- | jim-aio.c | 24 |
1 files changed, 18 insertions, 6 deletions
@@ -832,6 +832,11 @@ static int aio_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv) jim_wide count = 0; jim_wide maxlen = JIM_WIDE_MAX; AioFile *outf = Jim_AioFile(interp, argv[0]); + /* Small, static buffer for small files */ + char buf[AIO_BUF_LEN]; + /* Will be allocated if the file is large */ + char *bufp = buf; + int buflen = sizeof(buf); if (outf == NULL) { return JIM_ERR; @@ -844,21 +849,28 @@ static int aio_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } while (count < maxlen) { - /* A reasonable compromise between stack size and speed */ - char buf[AIO_BUF_LEN]; jim_wide len = maxlen - count; - if (len > sizeof(buf)) { - len = sizeof(buf); + if (len > buflen) { + len = buflen; } - len = af->fops->reader(af, buf, len); + len = af->fops->reader(af, bufp, len); if (len <= 0) { break; } - if (outf->fops->writer(outf, buf, len) != len) { + if (outf->fops->writer(outf, bufp, len) != len) { break; } count += len; + if (count >= 16384 && bufp == buf) { + /* Heuristic check - for large copy speed-up */ + buflen = 65536; + bufp = malloc(buflen); + } + } + + if (bufp != buf) { + free(bufp); } if (JimCheckStreamError(interp, af) || JimCheckStreamError(interp, outf)) { |