Mindkét parancsot kipróbáltam, és a find | grep "filename" parancs sokszor lassabb, mint az egyszerű find "filename" parancs.

Mi lenne a megfelelő magyarázat erre a viselkedésre?

Megjegyzések

  • Ön minden fájlt felsorol a kereséssel, majd továbbítja az adatokat a feldolgozáshoz ‘ saját keresés esetén hiányzik az a lépés, hogy az összes felsorolt fájlt átadja a kimenet elemzéséhez. Ez tehát gyorsabb lesz.
  • Milyen értelemben lassabb? A parancsok végrehajtása más ideig tart?
  • Ezt nem tudom helyileg reprodukálni ‘. Ha van valami, a time find "$HOME" -name '.profile' hosszabb időt jelent, mint a time find "$HOME" | grep -F '.profile'. (17s vs. 12s).
  • @JenniferAnderson többször is futottam. A 17 és 12 másodperc átlag. És igen, a grep variáció bárhol meg fog egyezni a find eredményben, míg a find -name csak pontosan egyezne (ebben az esetben).
  • Igen, a find filename gyors lenne . Feltételeztem, hogy ez elgépelés volt, és hogy az OP find -name filename -t jelentette. A find filename beállítással csak a (z) filename elemeket vizsgálnák (és semmi mást).

Válasz

(GNU find itt feltételezem)

Csak

A

find filename 

gyors lenne , mert csak filename -et, vagy a filename ha könyvtár, vagy hiba, ha ez a név nem létezik az aktuális könyvtárban. Nagyon gyors működés, hasonló a ls filename -hez (de rekurzív, ha filename könyvtár).

ellentétben,

find | grep filename 

lehetővé tenné a find számára az összes név listájának létrehozását az aktuális könyvtár és az alatta található, amelyet grep akkor szűrne. Ez nyilvánvalóan sokkal lassabb művelet lenne.

Feltételezem, hogy ami valójában A rendeltetés

find . -type f -name "filename" 

Ez a filename -t keresi egy rendes fájl neveként bárhol az aktuális könyvtár vagy az alatt.

Ez ugyanolyan gyors (vagy összehasonlíthatóan gyors) lesz, mint a find | grep filename, de a grep megoldás megegyezik a filename vel az egyes megtalált nevek teljes elérési útjával, hasonlóan ahhoz, amit a -path "*filename*" a find.


A zavart abból a félreértésből fakadják, hogy find működik.

A segédprogram számos elérési utat használ, és az összes utat visszaadja ezen utak alatt.

Ezután korlátozza a visszaküldött neveket különféle tesztek segítségével, amelyek hatással lehetnek a fájlnévre, az elérési útra, az időbélyegzőre, a fájlméretre, a fájltípusra stb.

Amikor azt mondja, hogy

find a b c 

arra kéri find, hogy sorolja fel az összes elérhető nevet a három útvonal alatt a, b és c. Ha ezek véletlenül az aktuális könyvtárban található normál fájlok nevei, akkor ezeket visszaküldik. Ha bármelyikük véletlenül egy könyvtár neve, akkor az a könyvtár minden további nevével együtt visszatér.

Amikor megteszem

find . -type f -name "filename" 

Ez létrehozza az összes név listáját az aktuális könyvtárban (.) és az alatt. Ezután a -type f paranccsal korlátozza a rendes fájlok nevét, azaz nem könyvtárakat stb. Ezután további korlátozások vonatkoznak a nevekre, amelyek megfelelnek a filename kifejezésnek a -name "filename" használatával. A (z) filename karakterlánc lehet egy fájlnéven pörgő minta, például *.txt (ne felejtsd el idézni!).

Példa:

A következő úgy tűnik, hogy “megtalálja” a .profile nevű fájlt a saját könyvtáramban:

$ pwd /home/kk $ find .profile .profile 

De valójában csak az összes nevet adja vissza a .profile útvonalon (csak egy név van, és ez a fájl is).

Ezután cd egy szinttel feljebb és megpróbálom újra:

$ cd .. $ pwd /home $ find .profile find: .profile: No such file or directory 

A find parancs mostantól nem talál .profile nevű útvonalat.

Ha azonban megkapom, hogy megnézzem az aktuális könyvtárat, majd a visszaadott neveket csak .profile re korlátozom, akkor onnan is:

$ pwd /home $ find . -name ".profile" ./kk/.profile 

Megjegyzések

  • find filename csak filename -et adná vissza, ha a filename nem a könyvtár típusú lenne (vagy a könyvtár típusú lenne, de nem volt saját bejegyzése)

Válasz

Nem technikai magyarázat: Jacket keresem a tömegben gyorsabb, mint mindenkit keresni a tömegben, és kizárni az összes figyelmét Jack kivételével.

Megjegyzések

  • A probléma az, hogy az OP arra számít, hogy Jack legyél az egyetlen ember a tömegben. Ha igen, akkor ‘ szerencsések. A find jack felsorolja jack, ha ‘ egy , vagy a könyvtár összes neve, ha ‘ sa a könyvtár. ‘ félreértés a find működéséről.

Válasz

Még nem értettem a problémát, de további betekintést tudok nyújtani.

Mint Kusalananda esetében, a find | grep hívás egyértelműen gyorsabb a rendszeremen, aminek nincs sok értelme. Eleinte valamiféle pufferelési problémát feltételeztem; hogy a konzolra való írás lelassítja a következő fájlnév beolvasásához szükséges következő rendszerhívás időpontját. A csőbe történő írás nagyon gyors: kb. 40 MB / s még 32 bájtos írások esetén is (meglehetősen lassú rendszeremen; 300 MiB / s 1 MB-os blokkméret esetén). Így azt feltételeztem, hogy a find gyorsabban tud olvasni a fájlrendszerből, amikor csövekbe (vagy fájlokba) ír, így a fájlútvonalakat olvasó és a konzolra írt két művelet párhuzamosan futhat ( amelyet find egyetlen szál folyamatként önmagában nem tud megtenni.

Ez “s find “hiba

A két hívás összehasonlítása

:> time find "$HOME"/ -name "*.txt" >/dev/null real 0m0.965s user 0m0.532s sys 0m0.423s 

és

:> time find "$HOME"/ >/dev/null real 0m0.653s user 0m0.242s sys 0m0.405s 

azt mutatja, hogy a find valami hihetetlen hülyeséget csinál (bármi is legyen az). elég alkalmatlannak bizonyul a -name "*.txt" végrehajtásában.

A bemeneti / kimeneti aránytól

Gondolhatja, hogy a find -name győz, ha nagyon kevés írnivaló van. De az ist csak kínosabbá válik find. Akkor is veszít, ha egyáltalán nincs mit írni 200K fájlokkal (13 millió csővezeték-adat) szemben a grep esetén:

time find /usr -name lwevhewoivhol 

find lehet olyan gyors, mint grep, bár

Kiderült, hogy a find butasága a name vel nem terjed ki más tesztekre. Használjon helyette egy regexet, és a probléma megszűnt:

:> time find "$HOME"/ -regex "\.txt$" >/dev/null real 0m0.679s user 0m0.264s sys 0m0.410s 

Gondolom, ez hibának tekinthető. Hajlandó hibajelentést tenni? Az én verzióm a find (GNU findutils) 4.6.0

Megjegyzések

  • Mennyire ismételhető az időzítés? Ha először a -name tesztet hajtotta végre, akkor lassabb lehet, mert a könyvtár tartalma nincs gyorsítótárban. (A -name és a -regex tesztelésekor nagyjából ugyanannyi időt vesznek igénybe, legalább akkor, ha a gyorsítótár hatását figyelembe vették. természetesen lehet, hogy csak a find …)
  • @psmears egy másik változata. Természetesen ezeket a teszteket már többször elvégeztem. A gyorsítótár-problémát már az első válasz előtti kérdéshez fűzött megjegyzésekben is említettük. A find verzióm megtalálható (GNU findutils) 4.6.0
  • Miért meglepő, hogy a -name '*.txt' hozzáadása lelassul find? Pluszmunkát kell végeznie, tesztelve az egyes fájlneveket.
  • @Barmar Egyrészt ez a extra munka rendkívül gyorsan elvégezhető. Másrészt ez a többletmunka más munkát takarít meg. find kevesebb adatot kell írnia. A csövekbe írás pedig sokkal lassabb művelet.
  • A lemezre írni nagyon lassan, a csövekre írni nem olyan rossz, csak egy kernelpufferre másol. Ne feledje, hogy az első teszt során, ha többet ír a /dev/null címre, valahogyan kevesebb a rendszeridő.

Válasz

Megjegyzés : Feltételezem, hogy find . -name filename (különben különböző dolgokat keres; find filename valójában egy fájlnév nevű útvonalat keresi, amely szinte semmilyen fájlt nem tartalmazhat, ezért nagyon gyorsan kiléphetünk).


Tegyük fel, hogy van egy könyvtárad, amely ötezer fájlt tárol. A legtöbb fájlrendszerben ezeket a fájlokat egy fa struktúrában tárolják, amely lehetővé teszi bármelyik fájl gyors megtalálását.

Tehát, amikor megkéri a find fájlt, amelynek a nevét csak ellenőrizni kell, a find megkérdezi ahhoz a fájlhoz, és csak ahhoz a fájlhoz, az alapul szolgáló fájlrendszerhez, amely nagyon kevés oldalt fog elolvasni a tömegtárból. Tehát, ha a fájlrendszer megéri a sót, akkor ez a művelet sokkal gyorsabban fog futni, mint az egész fát bejárva az összes bejegyzés lekérése érdekében. / p>

Amikor a sima find fájlt kéri, akkor ez pontosan az, amit csinál, az egész fát bejárja, olvasva. Minden. Egyetlen. Bejegyzés. Nagy könyvtárakkal, ez problémát jelenthet (pontosan ez az oka annak, hogy számos szoftver, sok fájl tárolására a lemezen, két vagy három komponens mélységű “könyvtárfákat” hoz létre: így minden egyes levélnek kevesebb fájlt kell tárolnia) .

Válasz

Tegyük fel, hogy a / john / paul / george / ringo / beatles fájl létezik, és a keresett fájl “köveknek” hívják

find / stones 

A keresés összehasonlítja a “beatles” -et a “kövekkel” és eldobja, amikor az “s” és “b” don “t egyezik .

find / | grep stones 

Ebben az esetben a keresés átadja a “/ john / paul / george / ringo / beatles” parancsot a grepnek és a grepnek Végig kell járnom az egész utat, mielőtt megállapítanám, hogy egyezik-e.

A grep ezért sokkal több munkát végez, ezért hosszabb ideig tart

Megjegyzések

  • Kipróbálta már?
  • A karakterlánc-összehasonlítások költsége (rendkívül egyszerű és olcsó) teljesen eltörpül az IO (vagy csak a syscall, ha gyorsítótárban van) költsége
  • a grep nem ‘ ta karaktersorozat-összehasonlítás, a reguláris kifejezés-összehasonlítás, ami azt jelenti, hogy végig kell dolgoznia az egész sztringet, amíg meg nem találja egy meccs, vagy a végére ér. A könyvtárkeresések ugyanazok, bármi is legyen.
  • @Paranoid Hm, a find melyik verziójáról beszélsz? ‘ láthatóan nem olyan, mint a find I ‘ m, amelyet debianban szoktam használni.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük