Saya mencoba kedua perintah dan perintah find | grep 'filename'
berkali-kali lebih lambat daripada find 'filename'
perintah sederhana .
Apa penjelasan yang tepat untuk perilaku ini?
command-line
grep
find
search
file-search
yoyo_fun
sumber
sumber
time find "$HOME" -name '.profile'
laporkan waktu yang lebih lama daritime find "$HOME" | grep -F '.profile'
. (17 vs 12d).grep
variasi akan cocok di mana saja dalamfind
hasil, sedangkan pencocokan denganfind -name
hanya akan sama persis (dalam hal ini).find filename
pasti cepat . Saya agak berasumsi bahwa ini adalah kesalahan ketik dan yang dimaksud OPfind -name filename
. Denganfind filename
, hanyafilename
akan diperiksa (dan tidak ada yang lain).Jawaban:
(Saya menganggap GNU di
find
sini)Menggunakan adil
akan cepat, karena itu hanya akan kembali
filename
, atau nama-nama di dalamnyafilename
jika itu adalah direktori, atau kesalahan jika nama itu tidak ada di direktori saat ini. Ini adalah operasi yang sangat cepat, mirip denganls filename
(tetapi rekursif jikafilename
direktori).Sebaliknya,
akan memungkinkan
find
untuk menghasilkan daftar semua nama dari direktori saat ini dan di bawah, yanggrep
kemudian akan disaring. Ini jelas akan menjadi operasi yang jauh lebih lambat.Saya berasumsi bahwa apa yang sebenarnya dimaksudkan itu
Ini akan dicari
filename
sebagai nama file biasa di mana saja di direktori saat ini atau di bawah.Ini akan sama cepat (atau sebanding cepat) dengan
find | grep filename
, tetapigrep
solusinya akan cocokfilename
dengan path lengkap dari setiap nama yang ditemukan, sama dengan apa yang-path '*filename*'
akan dilakukan denganfind
.Kebingungan muncul dari kesalahpahaman tentang bagaimana cara
find
kerjanya.Utilitas mengambil sejumlah jalur dan mengembalikan semua nama di bawah jalur ini.
Anda kemudian dapat membatasi nama yang dikembalikan menggunakan berbagai tes yang dapat bertindak pada nama file, path, timestamp, ukuran file, jenis file, dll.
Kapan kamu berkata
Anda meminta
find
daftar setiap nama yang tersedia di bawah tiga jalura
,b
danc
. Jika ini adalah nama-nama file biasa di direktori saat ini, maka ini akan dikembalikan. Jika salah satu dari mereka kebetulan merupakan nama direktori, maka itu akan dikembalikan bersama dengan semua nama lebih lanjut di dalam direktori itu.Kapan saya melakukannya
Ini menghasilkan daftar semua nama di direktori saat ini (
.
) dan di bawah. Kemudian itu membatasi nama-nama untuk orang-orang dari file biasa, yaitu bukan direktori dll, dengan-type f
. Lalu ada batasan lebih lanjut untuk nama yang cocokfilename
menggunakan-name 'filename'
. Stringfilename
mungkin merupakan pola globbing nama file, seperti*.txt
(ingatlah untuk mengutipnya!).Contoh:
Tampaknya ini "menemukan" file yang dipanggil
.profile
di direktori home saya:Tetapi pada kenyataannya, itu hanya mengembalikan semua nama di jalan
.profile
(hanya ada satu nama, dan itu dari file ini).Lalu saya
cd
naik satu level dan coba lagi:The
find
perintah sekarang tidak dapat menemukan jalan yang disebut.profile
.Namun, jika saya mendapatkannya untuk melihat direktori saat ini, dan kemudian membatasi hanya nama yang dikembalikan
.profile
, ia juga menemukannya dari sana:sumber
find filename
akan kembali hanyafilename
jikafilename
bukan dari direktori tipe (atau direktori tipe, tetapi tidak memiliki entri sendiri)Penjelasan Non-Teknis: Mencari Jack di tengah keramaian lebih cepat daripada mencari semua orang di kerumunan dan menghilangkan semua dari pertimbangan kecuali Jack.
sumber
find jack
akan daftarjack
apakah itu file yang dipanggiljack
, atau semua nama dalam direktori jika itu adalah direktori. Ini adalah kesalahpahaman tentang carafind
kerjanya.Saya belum mengerti masalahnya tetapi bisa memberikan beberapa wawasan lagi.
Seperti untuk Kusalananda,
find | grep
panggilan itu jelas lebih cepat di sistem saya yang tidak masuk akal. Pada awalnya saya mengasumsikan semacam masalah buffering; bahwa menulis ke konsol memperlambat waktu ke syscall berikutnya untuk membaca nama file berikutnya. Menulis ke pipa sangat cepat: sekitar 40MiB / s bahkan untuk penulisan 32-byte (pada sistem saya yang agak lambat; 300 MiB / s untuk ukuran blok 1MiB). Jadi saya berasumsi bahwafind
dapat membaca dari sistem file lebih cepat ketika menulis ke pipa (atau file) sehingga dua operasi membaca jalur file dan menulis ke konsol dapat berjalan secara paralel (yangfind
sebagai proses thread tunggal tidak dapat dilakukan sendiri.Itu
find
salahMembandingkan dua panggilan
dan
menunjukkan bahwa
find
melakukan sesuatu yang sangat bodoh (apa pun itu). Itu ternyata sangat tidak kompeten dalam mengeksekusi-name '*.txt'
.Mungkin tergantung pada rasio input / output
Anda mungkin berpikir itu
find -name
menang jika sangat sedikit untuk ditulis. Tapi aku semakin memalukanfind
. Kehilangan bahkan jika tidak ada yang menulis sama sekali terhadap 200 ribu file (13 juta data pipa) untukgrep
:find
bisa secepatgrep
, meskipunTernyata
find
kebodohan denganname
tidak meluas ke tes lain. Gunakan regex sebagai gantinya dan masalahnya hilang:Saya kira ini bisa dianggap bug. Adakah yang mau mengajukan laporan bug? Versi saya adalah find (GNU findutils) 4.6.0
sumber
-name
tes pertama, maka mungkin lebih lambat karena isi direktori tidak di-cache. (Ketika pengujian-name
dan-regex
saya menemukan mereka mengambil kira-kira waktu yang sama, setidaknya sekali efek cache telah dipertimbangkan. Tentu saja itu mungkin versi yang berbeda darifind
...)find
Versi saya adalah find (GNU findutils) 4.6.0-name '*.txt'
memperlambatfind
? Itu harus melakukan pekerjaan ekstra, menguji setiap nama file.find
harus menulis lebih sedikit data. Dan menulis ke pipa adalah operasi yang jauh lebih lambat./dev/null
entah bagaimana menggunakan lebih sedikit waktu sistem.Perhatikan : Saya berasumsi maksud Anda
find . -name filename
(jika tidak, Anda mencari hal-hal yang berbeda;find filename
sebenarnya mencari ke jalur yang disebut nama file , yang mungkin hampir tidak berisi file, maka keluar dengan sangat cepat).Misalkan Anda memiliki direktori yang menampung lima ribu file. Pada kebanyakan sistem file, file-file ini sebenarnya disimpan dalam struktur pohon , yang memungkinkan untuk dengan cepat menemukan satu file yang diberikan.
Jadi, ketika Anda meminta
find
untuk mencari file yang namanya hanya membutuhkan memeriksa,find
akan meminta untuk itu file, dan file itu saja, untuk filesystem yang mendasari, yang akan membaca sangat sedikit halaman dari mass storage. Jadi jika filesystem-nya bernilai garam, operasi ini akan berjalan jauh lebih cepat daripada melintasi seluruh pohon untuk mengambil semua entri.Ketika Anda meminta dataran
find
namun itu yang Anda lakukan, Anda melintasi seluruh pohon, membaca. Setiap. Tunggal. Masuk. Dengan direktori besar, ini mungkin menjadi masalah (itu persis alasan mengapa beberapa perangkat lunak, perlu menyimpan banyak file pada disk, akan membuat "pohon direktori" dalam dua atau tiga komponen: dengan cara ini, setiap daun hanya perlu menyimpan lebih sedikit file).sumber
Mari kita asumsikan file / john / paul / george / ringo / beatles ada dan file yang Anda cari disebut 'batu'
find akan membandingkan 'beatles' dengan 'stones' dan menjatuhkannya ketika 's' dan 'b' tidak cocok.
Dalam hal ini find akan melewati '/ john / paul / george / ringo / beatles' untuk grep dan grep harus bekerja jalan melalui seluruh jalan sebelum menentukan apakah itu cocok.
Oleh karena itu grep melakukan pekerjaan yang jauh lebih banyak dan karena itu dibutuhkan waktu lebih lama
sumber