Ketika Anda menjalankan ls
tanpa argumen, itu hanya akan membuka direktori, membaca semua konten, mengurutkannya dan mencetaknya.
Saat Anda menjalankan ls *
, pertama shell mengembang *
, yang secara efektif sama dengan apa yang sederhana ls
lakukan, membangun vektor argumen dengan semua file dalam direktori dan panggilan saat ini ls
. ls
kemudian harus memproses vektor argumen itu dan untuk setiap argumen, dan memanggil access(2)
¹ file untuk memeriksa keberadaannya. Maka itu akan mencetak output yang sama dengan yang pertama (sederhana) ls
. Baik pemrosesan shell dari vektor argumen besar dan ls
kemungkinan akan melibatkan banyak alokasi memori blok kecil, yang dapat memakan waktu. Namun, karena ada sedikit sys
dan user
waktu, tetapi banyak real
waktu, sebagian besar waktu akan dihabiskan menunggu disk, daripada menggunakan CPU melakukan alokasi memori.
Setiap panggilan ke access(2)
perlu membaca inode file untuk mendapatkan informasi izin. Itu berarti lebih banyak disk membaca dan mencari daripada sekadar membaca direktori. Saya tidak tahu seberapa mahal operasi ini pada GPFS Anda, tetapi karena perbandingan yang telah Anda tunjukkan ls -l
yang memiliki waktu berjalan yang sama dengan kasus wildcard, waktu yang diperlukan untuk mengambil informasi inode tampaknya mendominasi. Jika GPFS memiliki latensi yang sedikit lebih tinggi daripada sistem file lokal Anda pada setiap operasi baca, kami berharap itu akan lebih jelas dalam kasus ini.
Perbedaan antara kasus wildcard dan ls -l
50% dapat dijelaskan oleh pemesanan inode pada disk. Jika inode diletakkan berturut-turut dalam urutan yang sama dengan nama file dalam direktori dan ls -l
stat (2) ed file dalam urutan direktori sebelum menyortir, ls -l
mungkin akan membaca sebagian besar inode dalam sapuan. Dengan wildcard, shell akan mengurutkan nama file sebelum meneruskannya ls
, jadi ls
kemungkinan akan membaca inode dalam urutan yang berbeda, menambahkan lebih banyak gerakan kepala disk.
Perlu dicatat bahwa time
output Anda tidak akan mencakup waktu yang dibutuhkan oleh shell untuk memperluas wildcard.
Jika Anda benar-benar ingin melihat apa yang terjadi, gunakan strace(1)
:
strace -o /tmp/ls-star.trace ls *
strace -o /tmp/ls-l-star.trace ls -l *
dan lihat panggilan sistem yang dilakukan dalam setiap kasus.
¹ Saya tidak tahu apakah access(2)
itu benar-benar digunakan, atau sesuatu yang lain seperti stat(2)
. Tetapi keduanya mungkin memerlukan pencarian inode (saya tidak yakin apakah access(file, 0)
akan mem-bypass pencarian inode.)
ls
itu hanya dapat bertanya sistem file "apa yang anak-anak dari inode untukpwd
" di mana seperti denganls *
itu harus bertanya "apa saja anak-anak (dan apa file) dari inodea
" diikuti oleh b, c, d, dll. Satu pertanyaan vs banyak.