On Tuesday 09 October 2007 20:48, Heikki Linnakangas wrote:
> The new linux code is slightly but not much faster than the old one
> (3.04s vs 3.16s),
Test on my machine (three runs)
$ time ./sprintf-linux
./sprintf-linux 10-70-110
user 0m2.018s
user 0m2.024s
user 0m1.997s
$ time ./sprintf-linux-new
./sprintf-linux-new 10-70-110
user 0m1.839s
user 0m1.825s
user 0m1.817s
Re Linux printf speed:
I measured 10% run time reduction in top caused by faster generation
of /proc data. This 10% includes all overhead of printf(), read(),
copying data from kernel to userspace, parsing it in top etc.
Microbenchmark in userspace (running number() in a tight loop)
gave x3 performance increase.
> but it does beat glibc (5.20s) by a wide margin.
> However, preparsing the format string in gcc still beats the linux
> version hands down (0.82s).
You preparse "%d-%d-%d"? Into what?
I am from "small is beautiful" camp. I don't like "code growth
for everyone for the benefit of 5% of code which really needs
that last bit of speed" policy.
I hate 80MB+ Oracle executables with passion.
What problems do you see with this:
sprintf(char *dst, const char *fmt, ...)
{
char *d;
char *p = strchr(fmt, '%');
/* Literal string? */
if (!p) {
d = stpcpy(dst, fmt);
return d - dst;
}
va_start(ap, fmt);
/* Copy leading literal prefix */
d = mempcpy(dst, fmt, p - fmt);
fmt = p;
/* Fast path for "...%s...%s...%s..." */
while (p[1] == 's') {
char *q = va_arg(ap, char*);
d = stpcpy(d, q);
fmt += 2; /* skip %s */
p = strchr(fmt, '%');
if (!p) {
d = stpcpy(d, fmt);
return d - dst;
}
d = mempcpy(d, fmt, p - fmt);
fmt = p;
}
...continue with original sprintf code...
}
It's small code increase, only in ONE place,
catches even cases where format is not constant.
--
vda