Ускорение доступа к файловой системе?

Мое приложение сканирует часть файловой системы, и мои пользователи сообщили, что это было очень медленно, когда они сканировали сетевой диск. Тестируя мой код, я определил узкое место: методы File.isFile(), File.isDirectory(), и File.isHidden(), которые все звонят fs.getBooleanAttributes(File f). Этот метод, кажется, является очень медленным на сетевых дисках Windows. Как я могу улучшить производительность? Я могу постараться не называть этот метод в некотором роде?

10
задан Amanda S 18 December 2009 в 18:05
поделиться

5 ответов

Как вы составляете этот список файлов? Если вы не показываете все файлы в системе одновременно, у вас должны быть некоторые параметры ...

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

Возможно, если вы покажете код, вы являетесь используя для построения списка, мы могли бы найти некоторые другие области улучшения. (Почему вы не можете просто вывести тип на основе метода, используемого для сбора информации? Если вы вызываете такой метод, как GetFiles (), разве вы еще не знаете, что все возвращаемое - это файл?)

6
ответ дан 3 December 2019 в 18:33
поделиться

Защитный код часто вызывает методы isXYZ () , и это обычно хорошая практика. Однако, как вы обнаружили, иногда производительность низкая.

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

10
ответ дан 3 December 2019 в 18:33
поделиться

Я столкнулся с точно такой же проблемой

Решение для нашего случая было довольно простым: поскольку наша структура каталогов соответствовала стандарту (там, где не было каталога, в котором был бы символ '.' name), я просто следовал стандарту и применил очень простую эвристику: «в нашем случае каталоги не имеют символа '.' символ в его имени ". Эта простая эвристика резко сократила количество вызовов нашему приложению функции isDirectory () класса java.io.File.

Возможно, это ваш случай. Возможно, по структуре каталогов вы сможете узнать, является ли файл каталогом, только по соглашению об именах.

3
ответ дан 3 December 2019 в 18:33
поделиться

На случай, если вы еще не пробовали, вызвать getBooleanAttributes самостоятельно и выполнить необходимое маскирование будет значительно быстрее, если вы выполняете несколько проверок одного и того же файла. Хотя это не идеальное решение (и то, которое начинает подталкивать ваш код к привязке к платформе), оно может повысить производительность в 3 или 4 раза. Это довольно значительный прирост производительности, хотя и не так быстро, как должно быть.

Функциональность JDK7 java.nio.file.Path должна немного помочь в подобных делах.

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

0
ответ дан 3 December 2019 в 18:33
поделиться

Вот пример кода до и после использования listFiles и использования isDirectory для обхода дерева каталогов (мой код использует общий обратный вызов для фактического выполнения что-то с каждым каталогом и файлом; если бы я кодировал C #, это был бы делегат).

Как видите, подход listFiles на самом деле более компактен и понятен, а также немного быстрее на локальный диск (950 мс против 1000 мс) и диск LAN (26 секунд против 28 секунд), оба для 23 тысяч файлов.

Вполне возможно, что для удаленного подключенного диска ускорение может быть значительным, но я могу ' t проверьте это с работы. Как ни странно, скорость передачи через Windows RAS VPN на сетевой диск по-прежнему составляет всего около 10%.

Новый код

static public int processDirectory(File dir, Callback cbk, FileSelector sel) {
    dir=dir.getAbsoluteFile();
    return _processDirectory(dir.getParentFile(),dir,new Callback.WithParams(cbk,2),sel);
    }

static private int _processDirectory(File par, File fil, Callback.WithParams cbk, FileSelector sel) {
    File[]                              ents=(sel==null ? fil.listFiles() : fil.listFiles(sel));    // listFiles returns null if fil is not a directory
    int                                 cnt=1;

    if(ents!=null) {
        cbk.invoke(fil,null);
        for(int xa=0; xa<ents.length; xa++) { cnt+=_processDirectory(fil,ents[xa],cbk,sel); }
        }
    else {
        cbk.invoke(par,fil);                                                    // par can never be null
        }
    return cnt;
    }

Старый код

static public int oldProcessDirectory(File dir, Callback cbk, FileSelector sel) {
    dir=dir.getAbsoluteFile();
    return _processDirectory(dir,new Callback.WithParams(cbk,2),sel);
    }

static private int _processDirectory(File dir, Callback.WithParams cbk, FileSelector sel) {
    File[]                              ents=(sel==null ? dir.listFiles() : dir.listFiles(sel));
    int                                 cnt=1;

    cbk.invoke(dir,null);

    if(ents!=null) {
        for(int xa=0; xa<ents.length; xa++) {
            File                        ent=ents[xa];

            if(!ent.isDirectory()) {
                cbk.invoke(dir,ent);
                ents[xa]=null;
                cnt++;
                }
            }
        for(int xa=0; xa<ents.length; xa++) {
            File                        ent=ents[xa];

            if(ent!=null) {
                cnt+=_processDirectory(ent,cbk,sel);
                }
            }
        }
    return cnt;
    }
2
ответ дан 3 December 2019 в 18:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: