(受到评论的启发这个问题)
为什么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:/#