2009-11-10 14 views
12

Re:File. Esiste un'operazione costosa?

Qualcuno sa se si tratta di un'operazione particolarmente lenta o di blocco che potrebbe influire sulle prestazioni del server in un ambiente di grandi dimensioni?

+3

definire "grande ambiente" – jldupont

+1

Si noti inoltre che File.Exists() non ha quasi mai bisogno di essere chiamato.Solitamente viene utilizzato per convalidare una futura operazione di I/O, ma non può realmente farlo, poiché l'esistenza del file può cambiare tra l'ora in cui viene chiamata Exists e il momento in cui viene eseguita l'operazione IO. Di solito è meglio solo provare l'operazione che viene convalidata e vedere se funziona. Ovviamente, ci sono molti contro-esempi di questo, e la tua app può qualificarsi come uno di loro. –

+1

Un altro esempio di IO.File.Exists in uso è vedere se esiste un'immagine prima di visualizzarla e visualizzare un'alternativa in caso contrario. – SteveGSD

risposta

5

Blocco n. Lento, dipende da cosa lo stai confrontando. È abbastanza economico per quanto riguarda l'I/O, ma l'I/O è generalmente lento rispetto ad altre operazioni. Quindi, se devi usarlo, non farà male troppo male. Tuttavia, proverei a non chiamarlo più volte di quanto sia veramente necessario! :-)

7

Non penso che sia (le operazioni sui file sono fortemente ottimizzate e memorizzate nella cache nella maggior parte dei sistemi operativi) e la maggior parte delle altre operazioni hanno più probabilità di essere colpevoli qui (socket, accesso DB, elaborazione generale, ecc.). Ma, come al solito, il modo migliore è quello di profilare la tua applicazione e vedere se è un hotspot.

1

File.Exisits con kernel32.dll FindFirstFile gestore aperto per il file. Se l'handle risultante non è valido, restituisce false. Se valido, riempie la struttura dei dati con tutte le cose come LastAccessTime, CreationTime, dimensione del file e così via. E poi ritorna vero. Niente blocco.

2

Il migliore sarebbe eseguire alcuni test nel proprio ambiente. Ho un'app che può fare 10.000+ al secondo senza intoppi nei miei sistemi. Lo considero piuttosto veloce.

9

Nell'informatica, non esiste in realtà alcuna "operazione costosa", a meno che non si consideri in cosa è costoso.

Ad esempio, nel mondo reale, $ 2.000.000 per un oggetto sarebbe costoso? E se fosse il prezzo delle Bahamas? Sarebbe costoso allora? Che ne dici di un cartone di latte? È costoso?

La cosa che devi considerare è se File.Exists è costoso in termini di operazione complessiva che intendi fare e se effettivamente non hai alternative.

Se non si dispone di alternative, è importante se è costoso o no?

Ad esempio, se si verifica 1 se il file esiste, e se lo fa, lo si carica e si impiega un'ora a elaborarlo, quindi suppongo che non sarebbe considerato costoso.

Tuttavia, se lo si chiama 10 volte in un singolo ciclo, per capire se esiste un file, e quindi se lo fa, basta incrementare un numero, quindi potrebbe essere la singola operazione più costosa che si fa lì.

L'unico modo che si può sapere con certezza è in realtà misurare la durata della chiamata al metodo, rispetto a quello che si ha nella stessa operazione.

7

Nel 2016 non sembra essere molto costoso e non sembrano anche esserci alcuna vera differenza tra File.Exists e PathFileExists (Why is File.Exists() much slower when the file does not exist?). L'unica differenza che ho potuto misurare è che è più veloce per verificare la presenza di un file non esistente, allora uno esistente:

(Testato su uno SSD)

[DllImport("Shlwapi.dll", SetLastError = true, CharSet = CharSet.Auto)] 
private extern static bool PathFileExists(StringBuilder path); 

void Main() 
{ 
    var sw = Stopwatch.StartNew(); 
    for (int i = 0; i < 10000; i++) 
    { 
     File.Exists(@"c:\Home\Temp\test_.log"); 
    } 
    sw.Stop(); 
    sw.Dump("File.Exists = false"); 

    sw = Stopwatch.StartNew(); 
    for (int i = 0; i < 10000; i++) 
    { 
     File.Exists(@"c:\Home\Temp\test.log"); 
    } 
    sw.Stop(); 
    sw.Dump("File.Exists = true"); 

    var sb = new StringBuilder(@"c:\Home\Temp\test_.log"); 
    sw = Stopwatch.StartNew(); 
    for (int i = 0; i < 10000; i++) 
    { 
     PathFileExists(sb); 
    } 
    sw.Stop(); 
    sw.Dump("PathFileExists = false"); 

    sb = new StringBuilder(@"c:\Home\Temp\test.log"); 
    sw = Stopwatch.StartNew(); 
    for (int i = 0; i < 10000; i++) 
    { 
     PathFileExists(sb); 
    } 
    sw.Stop(); 
    sw.Dump("PathFileExists = true"); 

} 

Results

Problemi correlati