6

私は現在、ある種のデータベースベンチマークアプリケーションに取り組んでいます。基本的に、私がやろうとしているのは、特定の期間、データベースに対してすべて同じ操作(例:読み取り操作)を繰り返す特定の数のクライアントをスレッドを使用してシミュレートすることです。
この間、各スレッドで、データベースから回答を取得するための平均遅延を測定したいと思います。

私の最初の選択は、ThreadMXBeanのgetThreadCpuTime()メソッド(http://docs.oracle.com/javase/7/docs/api/java/lang/management/ThreadMXBean.html)に依存することでしたが、要点は、操作が実行されることです。測定するには速すぎます(操作前のgetThreadCpuTime()は、操作後のgetThreadCpuTime()と同じです)。

問題を理解して説明するために、少し実験を行いました。

public class ExampleClass {
class LongRunningThread extends Thread {
    private int n;
    public LongRunningThread(int n) {
        this.n = n;
    }
    public void run() {
        ArrayList l = new ArrayList();
        for (int i = 0; i < n; i++) {
            l.add(new Object());
        }
        long time = ManagementFactory.getThreadMXBean().getThreadCpuTime(this.getId());
        System.out.println("Long running thread " + this.getId() + " execution time: " + time);
    }
}

class MyThread extends Thread {
    int n;
    public MyThread(int n) {
        this.n = n;
    }
    public void run() {
        ArrayList l = new ArrayList();
        for (int i = 0; i < n; i++) {
            l.add(new Object());
        }
        long time = ManagementFactory.getThreadMXBean().getThreadCpuTime(this.getId());
        System.out.println("My thread " + this.getId() + " execution time: " + time);
    }
}

public static void main(String [] args) {
        System.out.println("Cpu time supported? " + ManagementFactory.getThreadMXBean().isThreadCpuTimeSupported());
    System.out.println("Cpu time enabled? " + ManagementFactory.getThreadMXBean().isThreadCpuTimeEnabled());
    for (int i = 1; i < 10; ++i) {
        new LongRunningThread(i*1000000).start();
    }

    for (int i = 1; i < 10; ++i) {
        new MyThread(i*100).start();
    }
}


Output:
Cpu time supported? true
Cpu time enabled? true
My thread 18 execution time: 0
My thread 26 execution time: 0
My thread 20 execution time: 0
My thread 22 execution time: 0
My thread 24 execution time: 0
My thread 21 execution time: 0
My thread 25 execution time: 0
My thread 19 execution time: 0
My thread 23 execution time: 0
Long running thread 9 execution time: 15600100
Long running thread 10 execution time: 15600100
Long running thread 11 execution time: 46800300
Long running thread 12 execution time: 31200200
Long running thread 14 execution time: 78000500
Long running thread 13 execution time: 78000500
Long running thread 17 execution time: 124800800
Long running thread 15 execution time: 140400900
Long running thread 16 execution time: 109200700

すべてのインスタンスの実行時間を取得できませんが、MyThreadインスタンスの問題はありませんLongRunningThread。私が言ったように、私の仮説は、最初のスレッドによって実行される操作が実際に測定するには速すぎるということです。私がやろうとしていることを達成する方法はありますか?このような短時間の実行スレッドの実行時間を測定することは可能ですか?

よろしくお願いします:)

4

3 に答える 3

3

このフレームワークhttp://metrics.codahale.com/を検討しましたか。非常に優れており、JMX を介してメトリックを公開するためのサポートが組み込まれています。

于 2013-02-02T18:25:06.597 に答える
1

このような短時間実行スレッドの実行時間を測定することは可能ですか?

ナノ秒時計で壁時計の時間を測定しなければ、答えはノーかもしれません。小さいループの場合、測定された CPU 時間はメソッドの精度よりも小さい場合があります。言うためのjavadocThreadMXBean.getThreadCpuTime(...)

指定された ID のスレッドの合計 CPU 時間をナノ秒単位で返します。戻り値はナノ秒の精度ですが、必ずしもナノ秒の精度ではありません。

考慮すべきことの 1 つは、CPU 時間が > 0 の場合は CPU 時間を取得し、== 0 の場合は壁時計時間を取得することです。

于 2013-02-02T20:11:06.667 に答える
0

あなたが次に使うことができるより簡単な解決策として:

class MyThread extends Thread {
    int n;
    public MyThread(int n) {
        this.n = n;
    }
    public void run() {
        long startTime = System.nanoTime();
        ArrayList l = new ArrayList(n);
        for (int i = 0; i < n; i++) {
            l.add(new Object());
        }
        long time = System.nanoTime() - startTime;
        System.out.println("My thread " + this.getId() + " execution time: " + time + " ns");
    }
}

ナノ秒の精度が必要ない場合は、System.currentTimeMillis()代わりに使用できます。

于 2013-02-02T18:43:31.883 に答える