Является ли File.Exists дорогой операцией? - PullRequest
14 голосов
/ 10 ноября 2009

Re: http://msdn.microsoft.com/en-us/library/system.io.file.exists.aspx

Кто-нибудь знает, если это особенно медленная или блокирующая операция, которая может повлиять на производительность сервера в большой среде?

Ответы [ 6 ]

11 голосов
/ 10 ноября 2009

В вычислениях на самом деле не существует такой вещи, как «дорогая операция», если только вы не считаете, что это дорого по отношению к.

Например, в реальном мире, будут ли 2 000 000 долларов за объект дорого? Что если это цена Багамских островов? Это будет дорого тогда? Как насчет коробки молока? Это дорого?

Вам нужно учесть, стоит ли File.Exists дорого с точки зрения общей операции, которую вы намереваетесь выполнить, и есть ли у вас какие-либо альтернативы.

Если у вас нет альтернатив, имеет ли значение, дорого это или нет?

Например, если вы выполните 1 проверку, существует ли файл, а затем, если он есть, загрузите его и потратите час на его обработку, то я бы предположил, что это не будет считаться дорогим.

Однако, если вы вызываете его 10 раз в одном цикле, чтобы выяснить, существует ли файл, а затем, если он существует, просто увеличить число, то это может быть самой дорогой единственной операцией, которую вы там выполняете.

Единственный способ узнать наверняка - это измерить, сколько времени занимает этот вызов метода, по сравнению с тем, что вы делаете в той же операции.

9 голосов
/ 08 марта 2016

В 2016 году он не кажется слишком дорогим, и, похоже, нет реальной разницы между File.Exists и PathFileExists ( Почему File.Exists () намного медленнее, если файл не есть ). Единственное различие, которое я могу измерить, состоит в том, что проверить несуществующий файл быстрее, чем существующий:

(протестировано на 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

7 голосов
/ 10 ноября 2009

Я не думаю, что это так (файловые операции сильно оптимизированы и кэшированы на большинстве ОС), и большинство других операций с большей вероятностью будут здесь виновниками (сокеты, доступ к БД, общая обработка и т. Д.). Но, как обычно, лучший способ - это профилировать ваше приложение и посмотреть, является ли оно горячей точкой.

5 голосов
/ 10 ноября 2009

Блокировка нет. Медленно, зависит от того, с чем вы сравниваете. Это довольно дешево с точки зрения ввода / вывода, но в целом ввод / вывод медленный по сравнению с другими операциями. Так что, если вы должны использовать его, это не будет слишком больно. Однако я бы постарался не называть это больше раз, чем это действительно необходимо! : -)

2 голосов
/ 10 ноября 2009

Лучше всего было бы запустить несколько тестов в вашей среде. У меня есть приложение, которое может работать со скоростью 10 000+ в секунду без сбоев в работе моей системы. Я считаю это довольно быстро.

1 голос
/ 10 ноября 2009

File.Exisits с kernel32.dll FindFirstFile открыть обработчик файла. Если полученный дескриптор недействителен, он возвращает false. Если он действителен, он заполняет структуру данных всеми данными, такими как LastAccessTime, CreationTime, размер файла и т. А потом верни истину. Ничего не блокирует.

...