Actions
Feature #9814
closedstrndup() performs pathologically
Start date:
2018-09-09
Due date:
% Done:
100%
Estimated time:
Difficulty:
Medium
Tags:
Gerrit CR:
Description
In investigating why statemaps were slower on illumos than other platforms, it was clear that we were spending an inordinate amount of time in strndup. Take the following program:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> /* * Made global to prevent the compiler from just optimizing the call away. */ char *s; int main() { size_t size = 10 * 1024 * 1024; int iter = 1000000; char *c = malloc(size); memset(c, '!', size - 1); c[size - 1] = '\0'; while (iter--) { s = strndup(c, 3); free(s); } }
On my Mac laptop (2.7 GHz Core i7):
$ time ./strndup real 0m0.084s user 0m0.076s sys 0m0.005s
On a 1U running SmartOS (3.5 GHz Haswell):
# time ./strndup real 8m47.107s user 8m47.051s sys 0m0.140s
The problem is that strndup needless calls strlcpy to do the actual copying – which will always return (and therefore determine) the length of the source string even when it exceeds the buffer length. This is needless; this should be a bcopy with an explicit NUL byte termination instead.
Running with the fix:
[root@4e773eea-7527-ee67-90ba-de62e536c367 ~]# time ./strndup real 0m0.051s user 0m0.045s sys 0m0.005s
I have also verified that the statemap code (which was the impetus for this) now runs with the expected performance.
Updated by Electric Monk over 3 years ago
- Status changed from New to Closed
git commit 159a0043473914c03b72d9f0c70c5aae42493748
commit 159a0043473914c03b72d9f0c70c5aae42493748 Author: Bryan Cantrill <bryan@joyent.com> Date: 2019-01-10T19:32:01.000Z 9814 strndup() performs pathologically Reviewed by: Robert Mustacchi <rm@joyent.com> Reviewed by: Patrick Mooney <patrick.mooney@joyent.com> Reviewed by: Toomas Soome <tsoome@me.com> Reviewed by: Garrett D'Amore <garrett@damore.org> Reviewed by: Andy Fiddaman <af@citrus-it.net> Approved by: Richard Lowe <richlowe@richlowe.net>
Actions