讓 Linux 的 ls 速度加快一倍

Linux ls 是列出系統內的檔案用的,平常使用沒什麼感覺,但是若檔案、目錄特別多的情況,速度就會慢到爆炸,慢的主要原因是什麼呢?

讓 Linux 的 ls 速度加快一倍

由文章與實作發現,原來 ls 會慢的主因是在於要秀出顏色(LS_COLORS),因為要秀出顏色,檔案有幾個,就要跑幾次的 lstat,若將這些關掉,就可以快上一倍的速度。

下述內容整理自此篇文章:When setting an environment variable gives you a 40x speedup

  1. mkdir /tmp/dont
  2. touch /tmp/dont/{1..10000} # 產生 10000 個檔案
  3. time ls --color=always /tmp/dont | wc -l
    10000
    real 0m0.051s
    user 0m0.028s
    sys 0m0.016s
  4. strace -c ls --color=always /tmp/dont | wc -l
    10000
    % time seconds usecs/call calls errors syscall
    ------ ----------- ----------- --------- --------- ----------------
    100.00 0.000184 0 10000 lstat
    0.00 0.000000 0 7 read
    0.00 0.000000 0 34 write
    0.00 0.000000 0 9 open
    0.00 0.000000 0 11 close
    0.00 0.000000 0 1 stat
    0.00 0.000000 0 10 fstat
    0.00 0.000000 0 19 mmap
    0.00 0.000000 0 12 mprotect
    0.00 0.000000 0 1 munmap
    0.00 0.000000 0 6 brk
    0.00 0.000000 0 2 rt_sigaction
    0.00 0.000000 0 1 rt_sigprocmask
    0.00 0.000000 0 3 3 ioctl
    0.00 0.000000 0 8 8 access
    0.00 0.000000 0 3 mremap
    0.00 0.000000 0 1 execve
    0.00 0.000000 0 9 getdents
    0.00 0.000000 0 1 getrlimit
    0.00 0.000000 0 2 2 statfs
    0.00 0.000000 0 1 arch_prctl
    0.00 0.000000 0 1 set_tid_address
    0.00 0.000000 0 1 set_robust_list
    ------ ----------- ----------- --------- --------- ----------------
    100.00 0.000184 10143 13 total
  5. unset LS_COLORS # 測試將 LC_COLORS 拿掉
  6. time ls --color=always dont | wc -l # 速度一樣差不多
    10000
    real 0m0.043s
    user 0m0.016s
    sys 0m0.020s
  7. 文章作者發現是下面幾個參數造成的
    • EXEC 00
    • SETUID 00
    • SETGID 00
    • CAPABILITY 00
  8. export LS_COLORS='ex=00:su=00:sg=00:ca=00:' # 所以將這幾個參數拿掉,lstat 就不會執行
  9. time strace -c ls --color=always /tmp/dont | wc -l # 速度快一倍
    10000
    % time seconds usecs/call calls errors syscall
    ------ ----------- ----------- --------- --------- ----------------
    0.00 0.000000 0 7 read
    0.00 0.000000 0 12 write
    0.00 0.000000 0 9 open
    0.00 0.000000 0 11 close
    0.00 0.000000 0 1 stat
    0.00 0.000000 0 10 fstat
    0.00 0.000000 0 19 mmap
    0.00 0.000000 0 12 mprotect
    0.00 0.000000 0 1 munmap
    0.00 0.000000 0 6 brk
    0.00 0.000000 0 2 rt_sigaction
    0.00 0.000000 0 1 rt_sigprocmask
    0.00 0.000000 0 2 2 ioctl
    0.00 0.000000 0 8 8 access
    0.00 0.000000 0 3 mremap
    0.00 0.000000 0 1 execve
    0.00 0.000000 0 9 getdents
    0.00 0.000000 0 1 getrlimit
    0.00 0.000000 0 2 2 statfs
    0.00 0.000000 0 1 arch_prctl
    0.00 0.000000 0 1 set_tid_address
    0.00 0.000000 0 1 set_robust_list
    ------ ----------- ----------- --------- --------- ----------------
    100.00 0.000000 120 12 total
    real 0m0.031s
    user 0m0.020s
    sys 0m0.008s

於是我原本 LC_COLORS 的設定

  • declare -x LS_COLORS="no=00:fi=00:di=01;36:ln=02;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.ogg=01;35:*.mp3=01;35:*.wav=01;35:"

要將 LS_COLORS='ex=00:su=00:sg=00:ca=00:' 加入,裡面只有 ex 是不同的,所以將 ex 改 00,在加入其餘的值,如下:

  • declare -x LS_COLORS="no=00:fi=00:di=01;36:ln=02;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.ogg=01;35:*.mp3=01;35:*.wav=01;35:ex=00:su=00:sg=00:ca=00:"

速度就能提昇一倍囉~

不過執行檔的顏色就無法顯示出來,所以這個設定可以另外寫成 Shell function 來處理,特別對多檔案的時候用的 ls

function mls() {
    export LS_COLORS="no=00:fi=00:di=01;36:ln=02;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.ogg=01;35:*.mp3=01;35:*.wav=01;35:ex=00:su=00:sg=00:ca=00:"
    ls "$@"
}

速度測試比較

  1. time ls --color dont/ | wc -l
    10000
    real 0m0.067s
    user 0m0.040s
    sys 0m0.020s
  2. time mls --color dont/ | wc -l
    10000
    real 0m0.030s
    user 0m0.020s
    sys 0m0.004s

作者: Tsung

對新奇的事物都很有興趣, 喜歡簡單的東西, 過簡單的生活.

發表迴響

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料