Project

General

Profile

Feature #9814

strndup() performs pathologically

Added by Robert Mustacchi about 1 year ago. Updated 9 months ago.

Status:
Closed
Priority:
Normal
Category:
lib - userland libraries
Start date:
2018-09-09
Due date:
% Done:

100%

Estimated time:
Difficulty:
Medium
Tags:

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.

History

#1

Updated by Electric Monk 9 months 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>

Also available in: Atom PDF