15

私は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
4

5 に答える 5

24

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);
  }
}
于 2012-08-10T18:37:27.883 に答える
23

File.lastModifiedファイルが最後に変更された日時を照会するために OS にアクセスする必要があります。これはキャッシュされていません。比較ごとに 2 回実行しており、Arrays.sortmergesort --を使用していO(n log n)ます。に 245 プラグインするnと、約 580 回の比較、または最終変更時刻を取得するための OS への 1100 回の呼び出しになります。つまり、1 秒あたり約 230 の最終変更呼び出しを取得できます。少し遅いように思えますが、JVM 内での比較よりも確かに妥当です。

Marko Topolnik abd NgSan が上で指摘したように、修正はすべてのファイルの最終変更時刻を最初にキャッシュすることです。File とその時間を組み合わせた新しいクラス オブジェクトを作成し、それらのオブジェクトを並べ替えます。そうすれば、 への呼び出しが 245 回だけFile.lastModifiedになり、ソートにかかる時間は約 1/5 になります。

于 2012-08-10T18:36:49.430 に答える
1

比較操作

@Override
public int compare(File f1, File f2) {
    return (int)(f1.lastModified() - f2.lastModified());
}  

は単なるゲッターではなく、ファイルシステムから情報を取得するための呼び出しを発行するため、lastModified()よりもパフォーマンスが高いため、ソートの応答時間が長くなりcompare()ます。

于 2012-08-10T18:38:52.810 に答える
1

よくわかりませんが、変更時刻を読み取るたびにディスク I/O を実行しているように思えます。File オブジェクトと一緒にオブジェクトの変更時刻を単純に取得してから並べ替えた方が速い場合があります

于 2012-08-10T18:37:15.773 に答える
0

O(nlogn) の平均実行時間の複雑さを持つ変更されたクイック ソート調整マージ ソートで Java に実装されたソート。
そのため、lastModifiedTime の取得などのファイル操作に集中する必要があります。これらのファイルは、ネットワーク遅延が発生するローカル ファイルまたは共有ドライブであると確信していますか?

于 2012-08-10T18:35:28.473 に答える