1

平均を計算し、巨大なファイルからいくつかの数値の根を抽出する必要があります。

1, 2, 3, 4, 5,\n
6, 7, 8, 9, 10,\n
11, 12, 13, 14,15,\n
...

これはコードです:

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;

public class App1{

    int res, c;
    double mean, root;
    ArrayList list = new ArrayList();

    public App1() {
        // einlesen
        Scanner sc = null;
        try {
            sc = new Scanner(new File("file.txt")).useDelimiter("[,\\s]+");
        } catch (FileNotFoundException ex) {
            System.err.println(ex);
        }
        while (sc.hasNextInt()) {
            list.add(sc.nextInt());
            res += (int) list.get(c);
            c++;
        }
        sc.close();

        // Mean
        mean = res / list.size();

        // Root
        root = Math.sqrt(mean);

        System.out.println("Mean: " + mean);
        System.out.println("Root: " + root);
    }

    public static void main(String[] args) {
    App1 app = new App1();
    }
}

並列化する方法はありますか?

平均を計算する前にすべての数値が必要なので、あるスレッドがファイルから数値をフェッチしている間、別のスレッドが計算することはできません。
ルートの抽出と同じこと: 平均がまだ計算されていない場合、スレッドは平均からルートを抽出できません。

Futureについて考えましたが、それは解決策でしょうか?

4

4 に答える 4

1

平均は単純に合計をカウントで割ったものなので、並列に平均を計算できます。値を並行して合計できず、それらも数えて、後で割り算を行うことができない理由はありません。

クラスを考えてみましょう:

public class PartialSum() {
    private final int partialcount;
    private final int partialsum;
    public PartialSum(int count, int sum) {
        partialsum = sum;
        partialcount = count;
    public int getCount() {
        return partialcount;
    }
    public int getSum() {
        return partialsum;
    }
}

のように、これは Future の戻り値の型である可能性がありますFuture<PartialSum>

そのため、ファイルを部分に分割し、その部分を個々のスレッドに送信する必要があります。

各スレッドは を計算しPartialSumます。その後、スレッドが完了すると、次のことができます。

int sum = 0;
int count = 0;
for(Future<PartialSum> partial : futures) {
    PartialSum ps = partial.get();
    sum += ps.getSum();
    count += ps.getCount();
}

double mean = (double)sum / count;
double root = ....
于 2013-11-11T23:01:31.853 に答える
0

いいえ、これを並列化する方法はありません。スレッドを使用しているように見えることもできますが、結果は非常に複雑になりますが、それでも以前とほぼ同じ速度で実行されます。

この理由は、ファイル アクセスはシングル スレッドであり、シングル スレッドである必要があり、ファイルからの読み取り以外に行うことは 2 つの追加操作だけだからです。したがって、最良の場合、これらの追加操作は並列化できますが、実行時間がほとんどかからないため、ゲインはせいぜい 5% から 10% 程度になります。そして、その時間は、スレッドの作成と保守によって打ち消されます (さらに悪いことに)。

物事をスピードアップするためにできることは、物事をリストに入れる部分を削除することです(後でそれらの値が必要ないと仮定します)。

 while (sc.hasNextInt()) {
   res += sc.nextInt();
   ++c;
 }

 mean = res / c;
于 2013-11-11T23:34:44.487 に答える