Dlaczego GNU znajduje się tak szybko w porównaniu z graficznymi narzędziami do wyszukiwania plików?

47

Próbuję znaleźć plik, który nie istnieje w moim katalogu domowym i wszystkich podkatalogach.

find ~/ -name "bogus"przekazuje mi te informacje po kilku sekundach, ale menedżer plików KDEdolphin potrzebował prawie 3 minuty, aby zrobić to samo. To odpowiada mojemu wcześniejszemu doświadczeniu z GNOMEbeagle .

Jak radzi findsobie z tym samym bardzo szybko, gdy wyszukiwanie graficzne (które jest bardziej intuicyjne w użyciu niż parametry wiersza poleceń) jest opóźnione?

Czerwony
źródło
Nie wiem, co to jest „Dolphin”, ale czy może też zagląda do plików?
Kusalananda
1
Jest to graficzny menedżer plików z KDE: kde.org/applications/system/dolphin Ma możliwość przeszukiwania plików, ale nie włączyłem tej opcji podczas tego krótkiego testu.
Czerwony
9
Czy szukałeś więcej niż raz w delfinie? Może to być „indeksowanie” za pierwszym razem. I „znajdź” też jest wolne. Spróbuj „zlokalizować”, jeśli plik jest starszy niż ostatni raz, gdy baza danych dla lokalizacji została zindeksowana ;-)
Rinzwind
Używam locateczęściej niż findi jest to szybsze w ogromnym folderze
phuclv
11
chociaż locatejest naprawdę świetny do wyszukiwania plików, jest to trochę OT, ponieważ używa zupełnie innego podejścia: finda narzędzia GUI, takie jak przeglądają Dolphindrzewo plików na żądanie, podczas gdy locateużywają wcześniej utworzonej struktury indeksu.
Michael Schaefers,

Odpowiedzi:

68

Patrząc konkretnie na Dolphin z Baloo, wydaje się, że wyszukuje metadane każdego pliku w domenie wyszukiwania, nawet jeśli wykonujesz proste wyszukiwanie nazw plików. Kiedy prześledzić file.soproces, widzę wywołań lstat, getxattri getxattrznowu dla każdego pliku, a nawet do ..wpisów. Te wywołania systemowe pobierają metadane dotyczące pliku, który jest przechowywany w innym miejscu niż nazwa pliku (nazwa pliku jest przechowywana w zawartości katalogu, ale metadane znajdują się w i- węzle ). Wielokrotne sprawdzanie metadanych pliku jest tanie, ponieważ dane znajdowałyby się w pamięci podręcznej dysku, ale może istnieć znacząca różnica między pytaniem o metadane a nie pytaniem o metadane.

findjest znacznie mądrzejszy. Stara się unikać niepotrzebnych wywołań systemowych. Nie zadzwoni, getxattrponieważ nie wyszukuje na podstawie rozszerzonych atrybutów. Podczas przeglądania katalogu może być konieczne wywołanie lstatniepasujących nazw plików, ponieważ może to być podkatalog do przeszukiwania rekurencyjnego ( lstatjest to wywołanie systemowe, które zwraca metadane pliku, w tym typ pliku, taki jak zwykły / katalog / symlink /…). Jednak findma optymalizacja: wie ile podkatalogów katalogu ma od jego liczby łącza i przestanie dzwoni lstatraz wie, że jest to ruch wszystkie podkatalogi. W szczególności w katalogu typu liść (katalogu bez podkatalogów),findsprawdza tylko nazwy, a nie metadane. Ponadto niektóre systemy plików przechowują kopię typu pliku we wpisie katalogu, więc findnawet nie musi dzwonić, lstatjeśli jest to jedyna potrzebna informacja.

Jeśli uruchomisz findz opcjami wymagającymi sprawdzenia metadanych, wykona więcej lstatpołączeń, ale nadal nie wykona lstatpołączenia z plikiem, jeśli nie potrzebuje informacji (na przykład dlatego, że plik jest wykluczony na podstawie poprzedniego warunku dopasowanie do nazwy).

Podejrzewam, że inne narzędzia wyszukiwania GUI, które odkrywają findkoło, są mniej sprytne niż narzędzie wiersza poleceń, które zostało poddane dekadom optymalizacji. Przynajmniej Dolphin jest wystarczająco sprytny, aby korzystać z lokalizowanej bazy danych, jeśli wyszukujesz „wszędzie” (z ograniczeniem, które nie jest jasne w interfejsie użytkownika, że ​​wyniki mogą być nieaktualne).

Gilles „SO- przestań być zły”
źródło
22
GNU find jest tak „sprytny”, że brakuje niektórych plików w niektórych typach systemów plików. Dobrze znanym błędem w znalezieniu GNU jest to, że nielegalnie przyjmuje, że liczba odsyłaczy do katalogu to 2 + number of sub-directories.Działa w systemach plików, które implementują błąd projektowy z systemu plików UNIX V7, ale nie we wszystkich systemach plików, ponieważ nie jest to wymóg POSIX . Jeśli chcesz uzyskać użyteczny numer wydajności dla GNU make, musisz określić -noleaf, aby GNU make zachowywał się poprawnie.
schily,
12
@schily, GNU findmógł mieć ten błąd już dawno temu, ale wątpię, abyś znalazł przypadek, w którym musisz określić to -noleafręcznie. AFAICT, przynajmniej w Linuksie getdents()(i readdir ()) informuje, które pliki są plikami katalogowymi w UDF, ISO-9660, btrfs, które nie mają rzeczywistych .lub ..wpisów i findzachowuje się tam OK. Czy znasz jeden przypadek, w którym GNU findwykazuje problem?
Stéphane Chazelas,
4
Wystarczy użyć tego zgniłego obrazu genio z Debiana, aby utworzyć system plików Rock Ridge przy użyciu „punktów graft”, a liczba linków w katalogu jest wartością losową. Ponieważ Rock Ridge implementuje liczbę linków i. / .., GNU find zwykle nie znajdzie wszystkich plików w takim systemie plików.
schily
4
@ StéphaneChazelas: Ostatnim razem, gdy sprawdzałem (dla pracy magisterskiej), błąd został naprawiony przez podanie dokładnie 2 oznaczonych znanych liści zamiast <= 2. Systemy plików, które nie implementują licznika 2+, zwracają 1 dla linku do katalogu, więc wszystko w porządku. Teraz, jeśli pewnego dnia ktoś stworzy system plików, który zawiera twarde linki do katalogów, które nie mają tej właściwości, ktoś będzie miał zły dzień.
Joshua
15
@schily, nie byłem w stanie uzyskać losowej liczby linków z punktami graft i RR z genisoimage 1.1.11 na Debianie i nawet jeśli edytuję binarnie obraz ISO, aby zmienić liczbę linków na losowe, nadal nie widzę żadnych problem z GNU find. W każdym razie strace -vpokazuje, że getdents()poprawnie zwraca d_type = DT_DIR dla katalogów, więc GNU find nie musi używać sztuczki polegającej na liczeniu linków.
Stéphane Chazelas,