aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2023-01-31 16:51:41 +1000
committerSteve Bennett <steveb@workware.net.au>2023-01-31 16:53:23 +1000
commite44134667c52674c0b9bfdab303dc8ddc1c933b8 (patch)
treeb2c2233f4d48ccfa4036be3261cad8991268aaad
parent5a09d43250a51c2dc3c76dfebf5184c75b1c410e (diff)
downloadjimtcl-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.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/jim-aio.c b/jim-aio.c
index bbe7a18..ea606cc 100644
--- a/jim-aio.c
+++ b/jim-aio.c
@@ -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)) {