我查了sorting files in directory by size using java array list&& How to sort an ArrayList by its elements size in Java?
我的问题是,实施比较器的最佳方法是什么,以便排序更快?我被告知, 100k文件的排序应该在几秒钟内完成,而不是几分钟,因为文件大小很长。 有没有更好的方法来实现比较器?
我的比较者是:
public static List<File> sortFilesBySize(List<File> xmlFileList) {
xmlFileList.sort(Comparator.comparing(File::length).reversed());
return xmlFileList;
}
,其中
private static List<File> xmlFileList = new ArrayList<File>();
xmlFileList填充为:
pathList = pathList.subList(0,filterCount);
for (Path filePath : pathList)
xmlFileList.add(filePath.toFile());
filterCount是我按照要排序的文件数进行过滤的方式
并将sortFilesBySize调用为:
long startSortMillis = System.currentTimeMillis();
sortFilesBySize(xmlFileList);
long timeInMillis = System.currentTimeMillis() - startSortMillis;
通过改变排序为5k,10k 20k等的文件数量,我得到了
可以观察到,20k后排序需要几分钟。有什么建议我可以降低排序时间吗?
我也抬头https://docs.oracle.com/javase/8/docs/api/java/io/File.html看看我是否可以改进目前的实施情况,但似乎什么都没有跳出来。
答案 0 :(得分:2)
确实是由File.length()
上的系统调用引起的。它们的数量随着文件数量的增加而增加。按照建议缓存它。你会发现排序时间几乎消失了。
答案 1 :(得分:1)
尝试缓存长度:
public static List<FileWithCachedLength> sortFilesBySize(List<FileWithCachedLength> xmlFileList) {
xmlFileList.sort(Comparator.comparing(FileWithCachedLength::length).reversed());
return xmlFileList;
}
其中:
public class FileWithCachedLength {
private final File file;
private final int length;
// getters omitted
public FileWithCachedLength( File f ) {
file = f;
length = f.length();
}
}
答案 2 :(得分:0)
正如其他人所说,这是由于File.length()
方法的成本。
如果你有这样的方法:
public static <T, R> Function<T, R> memoized(Function<? super T, ? extends R> f) {
Objects.requireNonNull(f);
Map<T, R> map = new HashMap<>();
return t -> map.computeIfAbsent(t, f);
}
您可以像这样使用它:
public static List<File> sortFilesBySize(List<File> xmlFileList) {
xmlFileList.sort(Comparator.comparing(memoized(File::length)).reversed());
return xmlFileList;
}
只会为每个文件调用一次File.length()
费用。
答案 3 :(得分:0)
感谢所有的答案,他们非常有帮助。我选择了MiguelKVidal建议的实现。
我从审核Java Pairs开始 - 来自http://www.baeldung.com/java-pairs。
实施后,我的排序时间很好而且很低。但走目录路径的时间更长: