3

スレッドを使用してファイルをソートしようとしています。ここに Sort.java があります:

この関数は、スレッドを使用してソートします

public static String[] threadedSort(File[] files) throws IOException {
      String sortedData[] = new String[0]; 
      int counter = 0; 
      boolean allThreadsTerminated = false;
      SortingThread[] threadList = new SortingThread[files.length];
      for (File file : files) {
          String[] data = getData(file);
          threadList[counter] = new SortingThread(data);
          threadList[counter].start();
          counter++;
      }
      while(!allThreadsTerminated) {
          allThreadsTerminated = true;
          for(counter=0; counter<files.length; counter++) {
              if(threadList[counter].getState() != Thread.State.TERMINATED) {
                  allThreadsTerminated = false;               
              }           
          }
      }
      for(counter=0; counter<files.length; counter++) {
          sortedData = MergeSort.merge(sortedData, threadList[counter].data);
      }
      return sortedData;
 }

この関数は通常どおりソートします

  public static String[] sort(File[] files) throws IOException {
    String[] sortedData = new String[0];
    for (File file : files) {
      String[] data = getData(file);
      data = MergeSort.mergeSort(data);
      sortedData = MergeSort.merge(sortedData, data);
    }
    return sortedData;
  }

両方の方法を使用して並べ替えると、通常の並べ替えはスレッド化されたバージョンよりも高速になります。その理由は何ですか?私は何かを見逃していましたか?

私のSortingThreadは次のようなものです:

public class SortingThread extends Thread {
    String[] data;
    SortingThread(String[] data) {
        this.data = data;
    }
    public void run() {
         data = MergeSort.mergeSort(data);        
    }  
}

パフォーマンスを元のスレッド化されていない実装と比較してスレッド化された実装を分析すると、2 番目の方が高速であることがわかります。そのような行動の理由は何ですか?相対的なパフォーマンスの向上について話す場合、間違っていなければ、スレッド化された実装の方が高速であると期待しています。

編集: 適切に機能する MergeSort があると仮定します。しかし、そのコードをここに投稿しても意味がありません。また、 getData() 関数は、ファイルから入力を取得するだけです。問題は、ファイル全体を配列に取り込んでいるという事実にあると思います。スレッドごとに異なる行を提供する必要があると思います:

private static String[] getData(File file) throws IOException {
    ArrayList<String> data = new ArrayList<String>();
    BufferedReader in = new BufferedReader(new FileReader(file));
    while (true) {
      String line = in.readLine();
      if (line == null) {
        break;
      }
      else {
        data.add(line);
      }
    }


    in.close();
    return data.toArray(new String[0]);
  }
4

4 に答える 4

1

まず、経過時間はどのように計測するのですか?同じプログラムで両方のテストを実行しますか? その場合、mergesort はおそらく最初のテストの実行中に Hotspot コンパイルを受けることに注意してください。各メソッドを 2 回実行し、2 回目の実行で時間を測定することをお勧めします

于 2015-06-07T07:59:21.863 に答える
0

CPU/コアはいくつありますか? このコードの問題の 1 つは、メイン スレッドが "while(!allThreadsT​​erminated)" ループで CPU 時間を費やし、スレッドの状態をアクティブにチェックすることです。CPU が 1 つある場合、実際の並べ替えを行う代わりに、CPU を無駄にしています。

while ループを次のように置き換えます。

 for(counter=0; counter<files.length; counter++) {
        threadList[counter].join();
 }
于 2015-06-07T08:06:53.793 に答える