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 atime 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 afind
eredményben, míg afind -name
csak pontosan egyezne (ebben az esetben). - Igen, a
find filename
gyors lenne . Feltételeztem, hogy ez elgépelés volt, és hogy az OPfind -name filename
-t jelentette. Afind 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
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
felsoroljajack
, ha ‘ egy , vagy a könyvtár összes neve, ha ‘ sa a könyvtár. ‘ félreértés afind
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 afind
…) - @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 lelassulfind
? 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.
find filename
csakfilename
-et adná vissza, ha afilename
nem a könyvtár típusú lenne (vagy a könyvtár típusú lenne, de nem volt saját bejegyzése)