Java Arrays.sort() Длительное время
Я использую функцию Java Arrays.sort()
для сортировки списка файлов по их последнему измененному времени. Сорт для 245 файлов занимает около 5 секунд. Это кажется слишком длинным для меня. Я чувствую, что это не должно занимать более 0,5 секунды. Это хорошее предположение? Что я делаю не так? ИЛИ это нормально?
public static class LastModifiedComparator implements Comparator<File> {
@Override
public int compare(File f1, File f2) {
return (int)(f1.lastModified() - f2.lastModified());
}
}
File folder = new File( "C:\\Whatever\\" );
File[] filesInFolder = folder.listFiles();
logger.debug("Starting File Sort");
Arrays.sort(filesInFolder, new LastModifiedComparator());
logger.debug("Done File Sort");
Вывод в журнале
2012-08-10 14:24:20,333 DEBUG http-8080-4 <ClassName>:73 - Starting File Sort
2012-08-10 14:24:25,915 DEBUG http-8080-4 <ClassName>:75 - Done File Sort
Ответы
Ответ 1
Вам нужно будет улучшить логику Comparator
. Вам нужно кешировать значения lastModified()
, потому что реализация этого метода выполняется довольно медленно. Я предлагаю обернуть экземпляры File
в сопоставимый объект вашего создания, который будет кэшировать значение:
public class FileLmWrapper implements Comparable<FileLmWrapper> {
public final File f;
public final long lastModified;
public FileLmWrapper(File f) {
this.f = f;
lastModified = f.lastModified();
}
public int compareTo(FileLmWrapper other) {
return Long.compare(this.lastModified, other.lastModified);
}
}
Ответ 2
File.lastModified
должен перейти в ОС для запроса, когда файл был последним изменен - он не кэширован. Вы делаете это дважды за сравнение, а Arrays.sort использует mergesort - O(n log n)
. Включение 245 для n
, что около 580 сравнений или 1100 вызовов ОС для получения последнего измененного времени. Это означает, что вы можете получить около 230 последних изменений в секунду. Кажется, что это немного медленнее, но, безусловно, более правдоподобно, чем сравнение в JVM с таким длинным
Как отмечает Marko Topolnik abd NgSan, исправление будет состоять в том, чтобы сначала кэшировать последнее модифицированное время для всех файлов. Я бы сделал это, создав новый объект класса, который объединяет файл и время, а затем сортирует эти объекты. Таким образом, у вас будет только 245 вызовов File.lastModified
, и сортировка займет примерно 1/5 раз.
Ответ 3
Я точно не знаю, но кажется, что он делает дисковый ввод-вывод каждый раз, когда вы читаете Модифицированное время - таким образом, медленность. Возможно, быстрее просто получить измененные времена в объекте вместе с объектом File, а затем отсортировать.
Ответ 4
Операция сравнения
@Override
public int compare(File f1, File f2) {
return (int)(f1.lastModified() - f2.lastModified());
}
является не только геттером, но и вызывает вызов для получения информации из файловой системы, поэтому более высокое время отклика, в частности, связано с производительностью lastModified()
, чем compare()
.
Ответ 5
Сортировка, реализованная в java в <удачном > модифицированном Quick Sort настроенном Merge Sort, который будет иметь среднюю сложность времени выполнения O (nlogn). Итак, нам нужно сконцентрироваться на ваших Файловых операциях, таких как получение lastModifiedTime. Вы уверены, что эти файлы являются локальными файлами или общим диском, который занимает латентность сети?