Measure java short time running thread execution time

时光怂恿深爱的人放手 提交于 2020-12-08 07:15:05

问题


I'm currently working on some sort of database benchmark application. Basically, what I'm trying to do is to simulate using threads a certain number of clients that all repeat the same operation (example: a read operation) against the database during a certain period of time.
During this time, I want, in each thread, to measure the average delay for getting an answer from the database.

My first choice was to rely on ThreadMXBean's getThreadCpuTime() method (http://docs.oracle.com/javase/7/docs/api/java/lang/management/ThreadMXBean.html) but the point is that the operation is done too quickly to be measured (getThreadCpuTime() before the operation is equal to getThreadCpuTime() after the operation).

I made a little experiment to understand and illustrate the problem:

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

I cannot get the execution time for all MyThread instances but no problem for LongRunningThread instances. Like I said, my hypothesis is that the operation done by the first threads happen too fast to be actually measured. Is there any way to achieve what I'm trying to do? Is it possible to measure the execution time for such short time running threads?

Thanks in advance for you help :)


回答1:


Have you considerd this framework http://metrics.codahale.com/. It's very very good and comes with built in support for exposing metrics via JMX




回答2:


Is it possible to measure the execution time for such short time running threads?

Without measuring wall-clock times with the nano-second clock, the answer may be no. For small loops, the measured CPU time may be smaller than the precision of the method. The javadocs for ThreadMXBean.getThreadCpuTime(...) say:

Returns the total CPU time for a thread of the specified ID in nanoseconds. The returned value is of nanoseconds precision but not necessarily nanoseconds accuracy.

One thing to consider would be to take the CPU time if it is > 0 and take the wall-clock time if it is == 0.




回答3:


as easier solution you can use next :

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");
    }
}

if you don't need nanoseconds precision you can use System.currentTimeMillis() instead.



来源:https://stackoverflow.com/questions/14664897/measure-java-short-time-running-thread-execution-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!