Java Arrays.sort() Take a Long Time

2022-09-03 03:36:14

我正在使用Java的函数按上次修改时间对文件列表进行排序。245 个文件的排序大约需要 5 秒钟。这对我来说似乎太长了。我觉得它不应该超过0.5秒。这是一个好的假设吗?我做错了什么?或者这听起来很正常?Arrays.sort()

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

你需要改进你的逻辑。您需要缓存这些值,因为该方法的实现非常慢。我建议将实例包装到您创建的可比较对象中,该对象将缓存该值:ComparatorlastModified()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-- .插入245 for,那大约是580个比较,或者1100次调用操作系统来获得上次修改时间。这意味着您每秒可以获得大约230个上次修改的调用。这似乎有点慢,但肯定比JVM中的比较花费那么长时间更合理。O(n log n)n

正如Marko Topolnik abd NgSan在上面指出的那样,修复方法是首先缓存所有文件的上次修改时间。为此,我将创建一个将 File 和该时间组合在一起的新类对象,然后对这些对象进行排序。这样,您就只有 245 个调用 ,排序所需的时间应该约为 1/5。File.lastModified


推荐