Thursday, June 08, 2006

ls minus L .vs. ls minus one

Having a lot of files in a directory can be quite troublesome if your script needs to process them. Very often people will run "ls -l" to find out what files are in the directory. If you are using this approach in your script, you may consider using "ls -1" (ls minus one) (if you want one filename per line) instead of "ls -l" (ls minus L) to avoid all the lstat (get file status) system calls.

Below compared the system calls between "ls -l", "ls -1" and "ls" for 20 files in a directory. The system under test is a 2x Intel(R) Xeon(TM) CPU 3.20GHz running Linux 2.4.21-4.ELsmp.

You can see "ls -l" has 3 times more system calls as "ls -1"/"ls"

for i in `seq 1 20`; do touch sample.$i; done

export PATH=/usr/bin:/bin
export LD_LIBRARY_PATH=/usr/lib:/lib

(a) strace ls -l > /dev/null 2> ../strace-ls-l.txt
(b) strace ls -1 > /dev/null 2> ../strace-ls-1.txt
(c) strace ls    > /dev/null 2> ../strace-ls.txt


system calls          (a)     (b)    (c)
------------------------------------------
brk                    5       5      5
close                 17       9      9
connect                2       -      -
execve                 1       1      1
exit_group             1       1      1
fcntl64                5       1      1
fstat64               15       9      9
getdents64             2       2      2
gettimeofday           1       -      -
getxattr             100       -      -
ioctl                  3       3      3
lstat64              100       -      -
mmap2                  9       4      4
munmap                 8       3      3
old_mmap              13      11     11
open                  52      31     31
read                  14       6      6
rt_sigaction           3       3      3
set_thread_area        1       1      1
socket                 2       -      -
stat64                15      15     15
uname                  1       1      1
write                  2       1      1
-----------------------------------------
Total                372     107    107

How about 10,000 files in a directory, which is not uncommon in some production systems.

$ for i in `seq 1 10000`; do touch sample.$i; done

$ time ls -l > /dev/null

real    0m0.134s
user    0m0.070s
sys     0m0.060s

$ time ls -1 > /dev/null

real    0m0.049s
user    0m0.050s
sys     0m0.000s
If we do a system call trace, you will find out the "ls -l" is very inefficient
  • "ls -l" made 20444 system calls
  • "ls -1" made 242 system calls

So next time when you do a "ls minus L", change L to one.

Labels: ,

0 Comments:

Post a Comment

<< Home