[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#492086: partman: menus are very slow

John Reiser wrote:
> First, avoid searching for "cat" every time.  The default search tries:
>    /usr/local/sbin/cat
>    /usr/local/bin/cat
>    /usr/sbin/cat
>    /usr/bin/cat
>    /sbin/cat
> before finding /bin/cat.  Instead: use 'which' or 'type' to do the search once,
> assign the result to a local variable, and expand the variable instead of
> searching:
>    CAT=$(which cat)
>    $($CAT $dir/default_response)
> Or, in nearly all cases the result is known ahead of time:
>    CAT=/bin/cat

So the question is, how much system time do the following failing system calls
actually take, when multiplied by the number of calls to "cat" made in
the lifetime of partman:

joey@kodama:~>PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin strace -f busybox sh -c 'cat /dev/null' 2>&1 |grep execv
[pid 32292] execve("/usr/local/sbin/cat", ["cat", "/dev/null"], [/* 45 vars */]) = -1 ENOENT (No such file or directory)
[pid 32292] execve("/usr/local/bin/cat", ["cat", "/dev/null"], [/* 45 vars */]) = -1 ENOENT (No such file or directory)
[pid 32292] execve("/usr/sbin/cat", ["cat", "/dev/null"], [/* 45 vars */]) = -1 ENOENT (No such file or directory)
[pid 32292] execve("/usr/bin/cat", ["cat", "/dev/null"], [/* 45 vars */]) = -1 ENOENT (No such file or directory)
[pid 32292] execve("/sbin/cat", ["cat", "/dev/null"], [/* 45 vars */]) = -1 ENOENT (No such file or directory)
[pid 32292] execve("/bin/cat", ["cat", "/dev/null"], [/* 45 vars */]) = 0

We can use a small C program to time an arbitrary number of failing exec's:

joey@kodama:~>cat foo.c 
main () {
        int i;
        for (i=0; i < 100000; i++)
                execve("/no/such/path/to/cat", 0);

joey@kodama:~>make foo
make: `foo' is up to date.
joey@kodama:~>time ./foo
Command exited with non-zero status 255
0.01user 0.23system 0:00.27elapsed 90%CPU (0avgtext+0avgdata 0maxresident)k

So, for 1 second of time to be used searching the PATH for it, d-i would
have to run cat 70000 times on modern hardware (the nslu2 is of course
~ 500 times slower). OTOH, actually running cat, as opposed to searching
for it, takes much much more time.. The same hardware can only run cat
1500 times per second.

Conclusion 1: System calls are much much faster than you'd think. Except that
successfully doing a fork+exec is slow.

Conclusion 2: Benchmark before optimising. In this case, trying to
optimise away the wrong system calls is a waste of time.

PS: Reordering PATH to put /usr/bin first and omit /usr/local/bin would
    be the easy way to optimise this, IF searching the path were actually
    a significant time sink. However, it does not appear to be.

PPS: Actually _eliminating_ calls to cat and other binaries in partman would
     of course help. A partman written in C should be 100 to 1000 times as
     fast as the current one.

see shy jo

Attachment: signature.asc
Description: Digital signature

Reply to: