Programim dhe zhvillim, javascript, python, php, html

Një mënyrë më e shpejtë e ecjes së Drejtorisë në vend të os.listdir?

Po përpiqem të përmirësoj performancën e elfinder, një menaxher skedari i bazuar në ajax (elRTE.ru).

Ai përdor os.listdir në një rekursve për të ecur nëpër të gjitha drejtoritë në mënyrë rekursive dhe për të pasur një sukses të performancës (si renditja e një dir me 3000 + skedarë kërkon 7 sekonda).

Po përpiqem të përmirësoj performancën sepse këtu është funksioni i ecjes:

        for d in os.listdir(path):
            pd = os.path.join(path, d)
            if os.path.isdir(pd) and not os.path.islink(pd) and self.__isAccepted(d):
                tree['dirs'].append(self.__tree(pd))

Pyetjet e mia janë:

  1. Nëse ndryshoj os.walk në vend të os.listdir, a do të përmirësonte performancën?
  2. po të përdorni dircache.listdir() ? memorie TË GJITHA direktoriumin/nëndirek përmbajtjen me kërkesën fillestare dhe kthen rezultatet e cache-it, nëse nuk ka skedarë të rinj të ngarkuar ose nuk ka ndryshime në skedar?
  3. A ka ndonjë metodë tjetër të ecjes në Directory e cila është më e shpejtë?
  4. Ndonjë shfletues tjetër skedari nga ana e serverit që shkruhet shpejt në python (por unë preferoj ta bëj këtë të shpejtë)?

  • Për çfarë po i përdorni këto të dhëna? Nëse mund të përballoni ta bëni rekursionin me përtesë (thirrni os.listdir() vetëm kur keni nevojë për përmbajtjen, jo automatikisht kur gjeni një drejtori të re), atëherë mund të amortizoni koston për shumë kërkesa. Kështu punojnë në praktikë shumica e menaxherëve të skedarëve. 02.07.2010
  • Këto të dhëna janë për një menaxher skedari të bazuar në ajax, i quajtur elfinder nga elrte.ru. është e bukur, por problemi është shumë i ngadalshëm për shkak të funksionit që kam ngjitur. E juaja duket praktike, unë do ta ndryshoj atë për të kërkuar çdo drejtori në vend të të gjithë në mënyrë rekursive. 02.07.2010
  • os.walk() nuk do të jetë më i shpejtë se funksioni juaj i ecjes sepse ata bëjnë kryesisht të njëjtat gjëra. os.walk() përdorni os.listdir(), os.pathisdir(), etj. Kontrolloni kodin e os.walk() dhe do të shihni! 02.07.2010
  • Përditësim 2017: Shumë informacione janë të vjetruara këtu tani. Gjegjësisht, os.walk nuk përdor më listdir, tani po përdor scandir më të shpejtë. 23.02.2017
  • @wim cilin version filloi të përdorte? Nuk disponohet në 2.7 apo jo? 25.02.2017

Përgjigjet:


1

Unë thjesht po përpiqesha të kuptoja se si të shpejtoja os.walk në një sistem skedarësh të madh (350,000 skedarë të shpërndarë në rreth 50,000 drejtori). Unë jam në një kuti linux duke përdorur një sistem skedari ext3. Zbulova se ka një mënyrë për ta përshpejtuar këtë për rastin TIM.

Në mënyrë të veçantë, duke përdorur një ecje nga lart-poshtë, sa herë që os.walk kthen një listë me më shumë se një direktori, unë përdor os.stat për të marrë numrin inode të çdo drejtorie dhe për të renditur listën e drejtorive sipas numrit inode. Kjo bën që ecja të vizitojë më së shumti nëndirektoritë në rend inode, gjë që redukton kërkimet e diskut.

Për rastin tim të përdorimit, ajo shpejtoi ecjen time të plotë të drejtorisë nga 18 minuta në 13 minuta ...

19.01.2011
  • Faleminderit shumë, kjo është një ide shumë interesante! do ta testoj! 12.01.2012
  • Në fakt kjo është mënyra më e shpejtë. Faleminderit, por përgjigja është zgjedhur tashmë. 08.08.2013
  • Mashtrim i bukur garlon4, është e vështirë të mendosh në këtë mënyrë pa sugjerimin tuaj. Dhe @V3ss0n, mendoj se mund ta ndryshoni përgjigjen tuaj të zgjedhur në çdo kohë, nëse dëshironi. 19.10.2013
  • Nëse performanca juaj është thelbësore, nuk keni nevojë për transportueshmëri sepse jeni në Linux dhe lista juaj është statike. Ju nuk merrni shpesh skedarë të rinj. Atëherë do të mendoja të ekzekutoja një proces të jashtëm duke përdorur komandën vendase si 'find', ose madje të ekzekutoja një skript c si: stackoverflow.com/questions/4204666/ dhe nxirrni ato në një skedar dhe më pas lexoni këtë skedar nga python. Kjo është një zgjidhje shumë më e shpejtë në skenarin e dhënë. 06.06.2017
  • Në rastin tim të përdorimit, unë në mënyrë eksplicite nuk e dija nëse skedarët dhe drejtoritë kishin ndryshuar apo jo (kjo është arsyeja pse po i ndiqja ato). 09.06.2017

  • 2

    A e kontrollove scandir (më parë betterwalk)? Nuk e kam provuar vetë, por ka një diskutim rreth tij këtu dhe një tjetër këtu. Ai pretendon se ka një shpejtësi prej 3~10x në MacOSX/Linux dhe 7~50x në Windows duke shmangur thirrjet e tepërta në os.stat(). Është gjithashtu i përfshirë tani në bibliotekën standarde që nga Python 3.5.

    os.walk() i integruar i Python është dukshëm më i ngadalshëm nga sa duhet, sepse -- përveç thirrjes së listdir() në çdo drejtori -- ai thërret stat() në çdo skedar për të përcaktuar nëse emri i skedarit është një drejtori ose jo. Por si FindFirstFile / FindNextFile në Windows ashtu edhe readdir në Linux/OS X tashmë ju tregojnë nëse skedarët e kthyer janë drejtori apo jo, kështu që nuk nevojiten thirrje të mëtejshme të sistemit. Me pak fjalë, ju mund të zvogëloni numrin e thirrjeve të sistemit nga rreth 2N në N, ku N është numri total i skedarëve dhe drejtorive në pemë.

    Në praktikë, heqja e të gjitha atyre thirrjeve shtesë të sistemit e bën os.walk() rreth 7-50 herë më të shpejtë në Windows dhe rreth 3-10 herë më shpejt në Linux dhe Mac OS X.

    Nga readme e projektit.

    13.11.2015
  • Unë do ta provoj, është mirë. 16.11.2015
  • scandir është përfshirë në modulin os të Python 3.5. 22.05.2016
  • Shënim: scandir tani është përfshirë në Python dhe në fakt përdoret nga os.walk. Pra, nëse keni menduar të provoni scandir si një zëvendësim më të shpejtë, mund ta harroni këtë! 23.02.2017

  • 3

    Ju duhet të matni drejtpërdrejt në makinat (OS, sistemet e skedarëve dhe memoriet e tyre, etj) të interesit tuaj specifik -- nëse os.walk është apo jo më i shpejtë se os.listdir në një makinë / OS / FS specifike dhe krejtësisht të ndryshme, do t'ju tregojë shumë pak për performancën në i juaji.

    Nuk jam i sigurt se çfarë nënkuptoni me cachedir.listdir -- nuk ka modul/funksion standard të bibliotekës me atë emër. listdir tashmë lexon të gjithë direktoriumin me një gllënjkë (pasi duhet të renditë rezultatet) ashtu si edhe os.walk (pasi duhet të ndajë nëndirektoritë nga skedarët). Nëse, në varësi të platformës suaj, keni një mënyrë të shpejtë për t'u njoftuar në lidhje me ndryshimet e skedarëve/direktorive, atëherë ndoshta ia vlen ta ndërtoni pemën një herë dhe ta redaktoni atë gradualisht ndërsa vijnë njoftimet për ndryshime... por kjo varet nga frekuenca relative e ndryshimeve kundrejt kërkesave, e cila, përsëri, varet tërësisht nga tuaj rrethanat specifike të aplikimit.

    01.07.2010
  • Na vjen keq, rregulluar, dua të them dircache.listdir 02.07.2010
  • @V3ss0n, dircache nuk ka funksionuar kurrë veçanërisht mirë dhe më në fund është zhvlerësuar që nga Python 2.6 dhe është hequr që nga Python 3.0 -- definitivisht nuk do ta sugjeroja. 02.07.2010
  • Ok, kështu që do ta heqim atë atëherë :) Faleminderit! 02.07.2010

  • 4

    Në mënyrë:

    • Dyshoj se do të shihni shumë një përshpejtim midis os.walk dhe os.listdir, pasi që të dyja mbështeten në sistemin e skedarëve themelor. Në fakt, dyshoj se sistemi i skedarëve themelor do të ketë një efekt të madh në shpejtësinë e operacionit.

    • Çdo operacion i cache-it do të jetë dukshëm më i shpejtë se goditja e sistemit të skedarëve (të paktën për kontrollet e dyta dhe të mëvonshme).

    • Ju gjithmonë mund të shkruani ndonjë mjet (ose të thërrisni një komandë shell) që gjeneron listën e drejtorive jashtë Python, dhe ta thërrisni atë përmes modulit subprocess. Por kjo është pak e komplikuar, dhe unë do t'i drejtohesha kësaj zgjidhjeje vetëm nëse cache nuk funksiononte për ju.

    • Nëse nuk keni gjetur një shfletues skedari në dyqani i djathit, ndoshta nuk do ta gjeni.

    01.07.2010
  • Më duhet të krahasoj performancën e komandave listdir dhe guaskës. Dyshoj se do kenë dallim.. 02.07.2010

  • 5

    Si thua ta bësh atë në bash?

    import subprocess
    command = 'ls .... or something else'
    subprocess.Popen([command] ,shell=True) 
    

    Në rastin tim, i cili po ndryshonte lejet për mijëra skedarë, kjo ka funksionuar shumë më mirë.

    31.07.2013
  • Analizimi i linjave të komandës nuk është pythonic dhe hacky, unë shmang thirrjen e linjave të komandave kur është në dispozicion përmes python. dhe nuk është i lëvizshëm. Në rastin tim, nëse kam nevojë për qasje ssh në objektiv, përdor paramiko, kurrë ssh klient 08.08.2013
  • Nuk është i lëvizshëm - dakord. Unë kurrë nuk përmenda asgjë për ssh. Nëse thirrja e linjave të kamerave është 'nuk është pythonic dhe hacky' pse është përfshirë moduli i nënprocesit në python? Gjithsesi, unë kam sugjeruar bash-in vendas, i cili është shumë më i shpejtë se çdo python. 18.08.2013
  • ›Native bash i cili është shumë më i shpejtë në travesting Unë do të doja të shihja standardin e performancës për pretendimin tuaj. ›jo pythonic dhe hacky' pse moduli i nënprocesit përfshihet në python Jam i sigurt se nuk jeni njohur me atë që do të thotë pythonic. 23.08.2013
  • Unë në fakt po e konsideroja këtë ide vetëm për listat e rregullta të direktorive ... jo për pemët në këmbë. find mund të jetë një zgjidhje e shpejtë për ecjen e pemëve. Vërtetë nuk është pitonike, por nëse është shumë më e shpejtë, ndonjëherë duhet të kënaqemi. Sa herë që më duhet të md5 diçka, përdor nënprocesin, sepse sipas të njëjtit parim, është shumë më i shpejtë sesa ta ekzekutoj në python amtare. 05.04.2014

  • 6

    os.path.walk mund të rrisë performancën tuaj, për dy arsye:

    1) Nëse mund të ndaloni së ecuri përpara se të keni ecur gjithçka, atëherë me të vërtetë do të jetë më shpejt se listdir, edhe pse vërehet vetëm kur keni të bëni me pemë të mëdha

    2) Nëse po listoni drejtori të mëdha, atëherë mund të jetë e shtrenjtë ta ktheni listën nga listdir. (Nuk është e vërtetë, shikoni komentin e Alex më poshtë)

    Megjithatë, ndoshta nuk do të bëjë ndonjë ndryshim dhe në fakt mund të jetë më i ngadalshëm, për shkak të shpenzimeve shtesë potencialisht të shkaktuara duke thirrur funksionin tuaj visit dhe duke bërë të gjithë paketimin dhe zbërthimin e argumenteve shtesë.

    (Me të vërtetë mënyra e vetme për t'iu përgjigjur kësaj pyetjeje është ta provoni vetë - duhet të duhen vetëm disa minuta)

    01.07.2010
  • Si os.walk relativisht i ri ashtu edhe os.path.walk i vjetër dhe i ngjeshur domosdoshmërisht lexojnë çdo direktori tërësisht sepse duhet t'i paraqesin emrat në të si një ose dy lista (os.path.walk është specifikuar në dokumente si duke përdorur os.listdir, por si mendoni se e bën os.walk?-). Pra, (2) nuk vlen vërtet. 02.07.2010
  • Epo, fuçi. Unë ende i qëndroj këshillës sime që dikush duhet t'i testojë këto gjëra.. :-) 02.07.2010
  • kështu që kjo do të thotë asnjë ndryshim në performancë. Por të paktën me os.walk, nuk do të duhet të bëni: os.path.isdir(pd) dhe jo os.path.islink(pd) pasi do të japë skedarë/dirs veçmas apo jo? Alrtie do ta testoj dhe do t'ju njoftoj! 02.07.2010

  • 7

    Po kërkoni për fsdir. Është shkruar në C dhe është krijuar për të punuar me python. Është shumë më i shpejtë sesa të ecësh nëpër pemë me bibliotekat standarde të pitonëve.

    05.04.2014

    8

    E di që kjo është një temë e vjetër, por thjesht duhej të merrja të njëjtin vendim tani, kështu që të postoja rezultatet. Me të gjitha përditësimet në Python 3.5+, os.walk() është mënyra më e shpejtë për ta bërë këtë, krahasuar me os.listdir() dhe os.scandir().

    Po mblidhja skedarë brenda dy dosjeve kryesore dhe rreth 30 dosjesh në secilën dosje kryesore.

    files_list = [os.path.join(dir_, root, f)
                  for dir_ in folder_list
                  for root, dirs, files in os.walk(dir_)
                  for f in files
                  if (os.path.basename(f).startswith(prefix) and f.endswith(ext))]
    

    Rezultatet e testeve të mia:
    os.scandir(): 10,949 skedarë, 35,579052 sekonda
    os.listdir(): 10,949 skedarë, 35,197001 sekonda
    os.walk(): 10,949 skedarë, 01,544174 sekonda

    22.02.2021
    Materiale të reja

    Masterclass Coroutines: Kapitulli-3: Anulimi i korutinave dhe trajtimi i përjashtimeve.
    Mirë se vini në udhëzuesin gjithëpërfshirës mbi Kotlin Coroutines! Në këtë seri artikujsh, unë do t'ju çoj në një udhëtim magjepsës, duke filluar nga bazat dhe gradualisht duke u thelluar në..

    Faketojeni derisa ta arrini me të dhënat false
    A e gjeni ndonjëherë veten duke ndërtuar një aplikacion të ri dhe keni nevojë për të dhëna testimi që duken dhe duken më realiste ose një grup i madh të dhënash për performancën e ngarkesës...

    Si të përdorni kërkesën API në Python
    Kërkesë API në GitHub për të marrë depot e përdoruesve duke përdorur Python. Në këtë artikull, unë shpjegoj procesin hap pas hapi për të trajtuar një kërkesë API për të marrë të dhëna nga..

    Një udhëzues hap pas hapi për të zotëruar React
    Në këtë artikull, do të mësoni se si të krijoni aplikacionin React, do të mësoni se si funksionon React dhe konceptet thelbësore që duhet të dini për të ndërtuar aplikacione React. Learning..

    AI dhe Psikologjia — Pjesa 2
    Në pjesën 2 të serisë sonë të AI dhe Psikologji ne diskutojmë se si makineritë mbledhin dhe përpunojnë të dhëna për të mësuar emocione dhe ndjenja të ndryshme në mendjen e njeriut, duke ndihmuar..

    Esencialet e punës ditore të kodit tim VS
    Shtesat e mia të preferuara - Git Graph 💹 Kjo shtesë është vërtet e mahnitshme, e përdor përpara se të filloj të punoj për të kontrolluar dy herë ndryshimet dhe degët më të fundit, mund të..

    Pse Python? Zbulimi i fuqisë së gjithanshme të një gjiganti programues
    Në peizazhin gjithnjë në zhvillim të gjuhëve të programimit, Python është shfaqur si një forcë dominuese. Rritja e tij meteorike nuk është rastësi. Joshja e Python qëndron në thjeshtësinë,..