summaryrefslogtreecommitdiff
path: root/src/shared
diff options
context:
space:
mode:
authordzwdz2022-08-03 12:55:01 +0200
committerdzwdz2022-08-03 12:55:01 +0200
commitbdae1cb0bbd3dd7589a458d54cb85b4bc6d7556c (patch)
treebbc37b2965133f17c6fdd31e0bce1c1038049566 /src/shared
parentd9da70c7c6230b9698dc4a1dbc4d7f05794d2740 (diff)
shared/printf: caching
Everything other than %s and %x outputs a single char at once. The speedup is easily visible when e.g. hexdumping.
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/printf.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/src/shared/printf.c b/src/shared/printf.c
index 47d56f8..f019ac4 100644
--- a/src/shared/printf.c
+++ b/src/shared/printf.c
@@ -6,14 +6,31 @@ struct out_state {
void (*back)(void *, const char *, size_t);
void *backarg;
int written;
+
+ char *cache;
+ size_t cpos, clen;
};
-static int output(struct out_state *os, const char *buf, size_t len) {
- if (len) os->back(os->backarg, buf, len);
- os->written += len;
+static int flush(struct out_state *os) {
+ if (os->cpos) {
+ os->back(os->backarg, os->cache, os->cpos);
+ os->written += os->cpos;
+ os->cpos = 0;
+ }
return os->written;
}
+static void output(struct out_state *os, const char *buf, size_t len) {
+ if (os->cpos + len < os->clen) {
+ memcpy(os->cache + os->cpos, buf, len);
+ os->cpos += len;
+ return;
+ }
+ flush(os);
+ os->back(os->backarg, buf, len);
+ os->written += len;
+}
+
static void output_c(struct out_state *os, char c) {
output(os, &c, 1);
}
@@ -50,15 +67,20 @@ int __printf_internal(const char *fmt, va_list argp,
void (*back)(void*, const char*, size_t), void *backarg)
{
const char *seg = fmt; /* beginning of the current non-modifier streak */
+ char cache[64];
struct out_state os = {
.back = back,
.backarg = backarg,
+ .cache = cache,
+ .cpos = 0,
+ .clen = sizeof(cache),
};
for (;;) {
char c = *fmt++;
if (c == '\0') {
- return output(&os, seg, fmt - seg - 1);
+ output(&os, seg, fmt - seg - 1);
+ return flush(&os);
}
if (c != '%') continue;
output(&os, seg, fmt - seg - 1);