GNU neden grafiksel dosya arama yardımcı programları ile karşılaştırıldığında bu kadar hızlı buluyor?


47

Ana dizinde ve tüm alt dizinlerinde olmayan bir dosyayı bulmaya çalışıyorum .

find ~/ -name "bogus"Birkaç saniye sonra bana bu bilgiyi verir, ancak KDE'nin dolphindosya yöneticisi de aynı işlemi yapmak için yaklaşık 3 dakikaya ihtiyaç duyuyordu. Bu benim önceki GNOMEbeagle deneyimlerime karşılık geliyor .

findGrafiksel arama (komut satırı parametrelerinden daha kullanımı kolay olan) geride kalırken aynı şeyi çok hızlı bir şekilde yapmayı nasıl başarır ?


Ben "Yunus" ne olduğunu bilmiyorum, ama belki de görünüyor içeride dosyalar?
Kusalananda

1
KDE'den grafiksel bir dosya yöneticisi: kde.org/applications/system/dolphin Dosyaların içinde arama yapabilme özelliğine sahip, ancak bu kısa test sırasında bu seçeneği etkin hale getirmedim.
Kırmızı

9
Yunusda birden fazla arama yaptınız mı? İlk seferinde “indeksleme” olabilir. Ve "bulmak" da yavaştır. Dosyayı bulmak için veritabanı en son dizine
eklenenden daha eskiyse "bul" u deneyin

locateDaha sık kullanıyorum findve büyük bir klasörde daha hızlı
phuclv

11
locatedosya bulmak için gerçekten harika olsa da, bu biraz OT, çünkü tamamen farklı bir yaklaşım kullanıyor: findve GUI araçları daha önce yaratılmış bir dizin yapısını kullanırken Dolphin, talep üzerine dosya ağacını geçiyor locate.
Michael Schaefers

Yanıtlar:


68

Özellikle Baloo ile Dolphin'e baktığımda, basit bir dosya adı araması yapsanız bile, arama alanındaki her dosyanın meta verilerini aramak gibi görünüyor. Ben iz zaman file.sosüreci, ben çağrıları bakın lstat, getxattrve getxattryine her dosya için ve hatta için ..girişler. Bu sistem çağrıları, dosya adından farklı bir konumda depolanan dosya hakkındaki meta verileri alır (dosya adı dizin içeriğinde depolanır, ancak meta veriler inode'dur ). Bir dosyanın meta verilerini birden çok kez sorgulamak, veriler disk önbelleğinde olacağı için ucuzdur, ancak meta verileri sorgulamakla meta verileri sorgulamak arasında önemli bir fark olabilir.

findçok daha zeki. Gereksiz sistem çağrılarından kaçınmaya çalışır. Bu demeyeceksin getxattruzatılabilir niteliklere dayalı aramaz çünkü. Bir dizine geçtiğinde, lstateşleşmeyen dosya adlarını çağırması gerekebilir, çünkü yinelemeli olarak arama yapmak için bir alt dizin olabilir ( lstatnormal / directory / symlink /… gibi dosya türünü içeren dosya meta verilerini döndüren sistem çağrısıdır). Bununla birlikte find, bir optimizasyon vardır: bir dizinin bağlantı sayısından kaç tane alt dizini lstatolduğunu bilir ve tüm alt dizinleri geçtiğini bildiğinde bir kez daha durur . Özellikle, bir yaprak dizininde (alt dizinleri olmayan bir dizin),findyalnızca verileri denetler, meta verileri değil. Ayrıca, bazı dosya sistemleri, dizin girişindeki dosya türünün bir kopyasını tutar; böylece, findihtiyaç lstatduyduğu tek bilgi buysa, aramasına gerek kalmaz .

findMeta verileri kontrol etmeyi gerektiren seçeneklerle çalışırsanız , daha fazla lstatarama yapar, ancak lstatbilgiye ihtiyaç duymuyorsa dosyada arama yapmaz (örneğin, dosya önceki bir koşulun dışında tutulduğu için) ismin eşleşmesi).

findTekerleği yeniden icat eden diğer GUI arama araçlarının, onlarca yıl süren optimizasyondan geçen komut satırı yardımcı programından benzer şekilde daha az akıllı olduğundan şüpheleniyorum . Dolphin, en azından, “her yerde” arama yaparsanız (veri tabanındaki sonuçların güncel olamayacağı konusunda bir sınırlama olmadan) bulma veritabanını kullanacak kadar zekidir.


22
GNU bulma o kadar "akıllı" ki bazı dosya sistemi tiplerindeki bazı dosyaları özlüyor. GNU’nun bulduğu bilinen hata, bir dizinin bağlantı sayısının yasadışı olduğu varsayımını 2 + number of sub-directories.yaptığıdır. Bu, POSIX gerekliliği olmadığından, UNIX V7 dosya sisteminden gelen tasarım hatasını uygulayan dosya sistemlerinde çalışır, ancak tüm dosya sistemlerinde işe yaramaz. . GNU markası için faydalı bir performans numarası almak isterseniz, -noleafGNU markasına doğru davranmasını söylemek için belirtmeniz gerekir .
schily

12
@schily, GNU finduzun zaman önce bu böceği yaşamış olabilir, ancak -noleafbugünlerde elle belirtmeniz gereken bir durum bulacağınızdan şüpheliyim . AFAICT, en azından Linux'ta getdents()(ve readdir ()), hangi dosyaların UDF, ISO-9660, gerçek olmayan btrfs .veya ..girişlerin bulunduğu dizin dosyaları olduğunu söyler ve findorada iyi davranır. GNU’nun findsorunu gösterdiği bir vaka biliyor musunuz ?
Stéphane Chazelas

4
Sadece "çürük noktaları" kullanarak bir Rock Ridge dosya sistemi oluşturmak için debian'ın bu çürük genisoimajını kullanın ve bir dizindeki link sayısı rastgele bir değerdir. Rock Ridge bir link sayısı ve. / .. uyguladığından, GNU find genellikle bu tür bir dosya sistemindeki tüm dosyaları bulamaz.
schily

4
@ StéphaneChazelas: Son kontrol ettiğimde (yüksek lisans tezi için), hata <= 2 yerine tam olarak bilinen 2 anlamına geldiğini iddia ederek giderildi. 2+ sayacını uygulamayan dosya sistemlerinin hepsi dizin bağlantı sayısı için 1 döndürür. her şey güzel. Şimdi eğer bir gün birileri bu özelliğe sahip olmayan dizinlerle bağlantı kuran bir dosya sistemi kurmuşsa, birileri kötü bir gün geçirecek.
Joshua,

15
@schily, Debian'da genisoimage 1.1.11 ile graft-puanları ve RR ile rastgele bağlantı sayıları alamadım ve bağlantı sayımlarını rastgele değerlere değiştirmek için iso görüntüsünü ikili olarak düzenlesem bile, hala herhangi bir şey göremiyorum GNU ile sorun find. Ve her durumda, dizinler için d_type = DT_DIR değerini doğru bir şekilde döndürdüğünü strace -vgösterir getdents(), böylece GNU bulmak link count hilesini kullanmak zorunda değildir.
Stéphane Chazelas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.