2009-11-10 10 views
12

Re:Czy File.Exists jest kosztowną operacją?

Czy ktoś wie, czy jest to operacja szczególnie powolna lub blokująca, która może wpłynąć na wydajność serwera w dużym środowisku?

+3

określenie „duże środowisko” – jldupont

+1

Zauważ też, że File.Exists() prawie nigdy nie musi być wywoływana.Zwykle jest używany do sprawdzania przyszłej operacji IO, ale tak naprawdę nie może tego zrobić, ponieważ istnienie pliku może się zmieniać między czasem wywołania Exists a czasem wykonania operacji IO. Zazwyczaj lepiej jest po prostu sprawdzić operację, która jest sprawdzana i sprawdzić, czy działa. Oczywiście jest wiele przykładów tego typu, a Twoja aplikacja może zostać zakwalifikowana jako jedna z nich. –

+1

Innym przykładem użycia pliku IO.File.Exists jest sprawdzenie, czy obraz istnieje przed jego wyświetleniem i wyświetlenie alternatywy, jeśli nie jest. – SteveGSD

Odpowiedz

5

Blokowanie nr. Powolny, zależy od tego, co porównujesz. Jest dość tani, jeśli chodzi o I/O, ale I/O generalnie jest powolny w porównaniu do innych operacji. Tak więc, jeśli musisz go użyć, nie zaszkodzi to zbyt źle. Jednak starałbym się nie nazywać tego więcej razy, niż jest to naprawdę konieczne! :-)

7

Nie sądzę, że tak (operacje na plikach są silnie zoptymalizowane i buforowane na większości systemów operacyjnych), a większość innych operacji jest bardziej prawdopodobna jako sprawcy (gniazda, dostęp do bazy danych, ogólne przetwarzanie itp.). Ale, jak zwykle, najlepszym sposobem jest faktycznie profilowanie aplikacji i sprawdzenie, czy jest to hotspot.

1

File.Exisits z kernel32.dll FindFirstFile Otwórz program obsługi do pliku. Jeśli wynikowy uchwyt jest nieprawidłowy, zwróci false. Jeśli jest poprawny, wypełnij strukturę danych wszystkimi takimi elementami jak LastAccessTime, CreationTime, rozmiar pliku i tak dalej. A potem wróć prawdę. Nic nie blokuje.

2

Najlepiej byłoby przeprowadzić testy w twoim środowisku. Mam aplikację, która może zrobić 10.000+ na sekundę bez problemów z moimi systemami. Uważam, że dość szybko.

9

W komputerach nie istnieje coś takiego jak "kosztowna operacja", chyba że rozważymy, co jest drogie w stosunku do.

Na przykład w świecie rzeczywistym, czy 2.000.000 USD na obiekt byłby kosztowny? Co jeśli jest to cena Bahamów? Czy to będzie kosztowne? A co powiesz na karton mleka? Czy to jest drogie?

Rzeczą, którą należy wziąć pod uwagę, jest to, czy File.Exists jest kosztowne pod względem ogólnej operacji, którą zamierzamy wykonać, i czy faktycznie istnieje alternatywa.

Jeśli nie masz żadnych alternatyw, czy ma to znaczenie, czy jest drogie, czy nie?

Na przykład, jeśli zrobisz 1 sprawdź, czy plik istnieje, a następnie, jeśli to zrobisz, załadujesz go i spędzasz godzinę na przetwarzaniu go, to zakładam, że nie byłby on uważany za drogi.

Jeśli jednak wywołasz go 10 razy w pojedynczej pętli, aby dowiedzieć się, czy plik istnieje, a jeśli tak, wystarczy zwiększyć liczbę, to może to być najdroższa pojedyncza operacja, jaką wykonujesz.

Jedynym sposobem, który możesz wiedzieć na pewno, jest faktyczne zmierzenie czasu trwania wywołania metody, w porównaniu z tym, co jeszcze robiłeś w tej samej operacji.

7

W 2016 roku nie wydaje się być bardzo kosztowne i nie wydaje się, aby istniały rzeczywiste różnice między File.Exists i PathFileExists (Why is File.Exists() much slower when the file does not exist?). Jedyną różnicą mogę zmierzyć jest to, że szybciej w celu sprawdzenia nieistniejącego pliku następnie istniejący:

(testowane na 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

Powiązane problemy