为什么 ls 比 echo * 慢很多?

为什么 ls 比 echo * 慢很多?

(受到评论的启发这个问题

为什么ls这比 慢得多echo *

$ time bash -c 'for i in {1..10000}; do ls -f > /dev/null; done'
bash -c 'for i in {1..10000}; do ls -f > /dev/null; done' 7.49s user 5.39s system 108% cpu 11.883 total
$ time bash -c 'for i in {1..10000}; do echo * > /dev/null; done'
bash -c 'for i in {1..10000}; do echo * > /dev/null; done' 0.16s user 0.25s system 98% cpu 0.415 total

我的意思是,当然,ls稍微慢一点是echo *有道理的,但这看起来很荒谬。

为什么会ls几乎是这样呢?

如果这与不需要速度有关ls,那么就没有理由yes 这么快

ls到底是什么导致它如此缓慢?

(我在笔记本电脑上的 Arch Linux 上使用 zsh。在 bash 上的时间相似。我还在(Linux Mint)台式计算机上进行了测试,结果相似。(ls -f速度更快,大约 7 秒,echo *仍然大约0.4 秒,这仍然是一个荒谬的差异。)在 Arch Linux 上,ls也是无别名的,但我没有为 Mint 烦恼,而且无论如何它也没有什么区别。)

答案1

使用strace,我们可以看到echo与 相比,对内核的系统调用要少得多ls

root@4a21b0630cba:/# strace -c ls
bin  boot  dev  etc  home  lib  lib32  lib64  libx32  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
  0.00    0.000000           0         7           read
  0.00    0.000000           0         1           write
  0.00    0.000000           0        10           close
  0.00    0.000000           0         9           fstat
  0.00    0.000000           0        26           mmap
  0.00    0.000000           0         9           mprotect
  0.00    0.000000           0         1           munmap
  0.00    0.000000           0         3           brk
  0.00    0.000000           0         2           rt_sigaction
  0.00    0.000000           0         1           rt_sigprocmask
  0.00    0.000000           0         2           ioctl
  0.00    0.000000           0         8           pread64
  0.00    0.000000           0         2         2 access
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         2         2 statfs
  0.00    0.000000           0         2         1 arch_prctl
  0.00    0.000000           0         2           getdents64
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         8           openat
  0.00    0.000000           0         1           set_robust_list
  0.00    0.000000           0         1           prlimit64
------ ----------- ----------- --------- --------- ----------------
100.00    0.000000                    99         5 total
root@4a21b0630cba:/# 
root@4a21b0630cba:/# 
root@4a21b0630cba:/# 
root@4a21b0630cba:/# strace -c echo *
bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
  0.00    0.000000           0         1           read
  0.00    0.000000           0         1           write
  0.00    0.000000           0         4           close
  0.00    0.000000           0         3           fstat
  0.00    0.000000           0         7           mmap
  0.00    0.000000           0         4           mprotect
  0.00    0.000000           0         1           munmap
  0.00    0.000000           0         3           brk
  0.00    0.000000           0         6           pread64
  0.00    0.000000           0         1         1 access
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         2         1 arch_prctl
  0.00    0.000000           0         2           openat
------ ----------- ----------- --------- --------- ----------------
100.00    0.000000                    36         2 total
root@4a21b0630cba:/# 

相关内容