0

I'm trying to measure the execution time of a loop, which is a simple Add Matrices. here's my code:

        //get integers m and n from user before this.
        long start,end,time;
        int[][] a = new int[m][n];
        int[][] b = new int[m][n];
        int[][] c= new int[m][n];

        start = getUserTime();

        for(int i = 0;i < m;i++)
        {
            for(int j = 0;j < n;j++)
            {
                c[i][j] = a[i][j]+b[i][j];
            }
        }
        end = getUserTime();

        time = end - start;


       /** Get user time in nanoseconds. */
       public long getUserTime() {
            ThreadMXBean bean = ManagementFactory.getThreadMXBean( );
            return bean.isCurrentThreadCpuTimeSupported( ) ?
            bean.getCurrentThreadUserTime() : 0L;
       }

the problem is, sometimes it returns 0, for example when I input 1000 as m and n. which means I have two 1000x1000 matrices being added. sometimes it returns 0 and sometimes 15ms (both keep getting repeated).

I don't know whether to believe 15ms or 0. and there is a big difference between them. I know the accuracy is OS dependent and not really nanoseconds accurate but 15miliseconds is way off to be an accuracy problem.

EDIT: the very goal of this code was to measure CPU performance on the loop. so if possible I want the effect of Compiler optimization and OS context switching etc to be minimal.

many thanks.

Ramin
  • 474
  • 6
  • 22
  • How can you get current time in nano seconds in Java? I'm not sure it's possible... – Alboz Oct 07 '14 at 19:54
  • is it ok for you to get the time in milliseconds? – Alboz Oct 07 '14 at 19:57
  • well I can't get them in nanoseconds because of OS's accuracy (using xp) but 15miliseconds difference just doesn't seem right. also here's more explanation on benchmarking like above: http://nadeausoftware.com/articles/2008/03/java_tip_how_get_cpu_and_user_time_benchmarking – Ramin Oct 07 '14 at 20:00
  • possible duplicate of [How do I calculate the elapsed time of an event in java?](http://stackoverflow.com/questions/238920/how-do-i-calculate-the-elapsed-time-of-an-event-in-java) – mdewitt Oct 07 '14 at 20:11
  • This is also a good answer to look at: http://stackoverflow.com/questions/1770010/how-do-i-measure-time-elapsed-in-java/1776053#1776053 – mdewitt Oct 07 '14 at 20:14

1 Answers1

3

You should use System.nanoTime(). (API Here)

From the documentation:

This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock time. The value returned represents nanoseconds since some fixed but arbitrary origin time (perhaps in the future, so values may be negative). The same origin is used by all invocations of this method in an instance of a Java virtual machine; other virtual machine instances are likely to use a different origin.

So the nanoTime() is fine for use to measure your execution time because the measurement will always be the same and it will use nanoseconds.

Set the start time to the current nano time.

start = System.nanoTime();

At the end of the loop set the end time to the current nano time

end = System.nanoTime();

To find the difference, which is the time it took to execute, just subtract like you do.

To make it easy, you can just change getUserTime() to return System.nano()

Example:

//get integers m and n from user before this.
long start,end,time;
int[][] a = new int[m][n];
int[][] b = new int[m][n];
int[][] c= new int[m][n];

start = getUserTime();

for(int i = 0;i < m;i++)
{
    for(int j = 0;j < n;j++)
    {
        c[i][j] = a[i][j]+b[i][j];
    }
}
end = getUserTime();

// You could use Math.abs() here to handle the situation where 
// the values could be negative
time = end - start;

/** Get user time in nanoseconds. */
public long getUserTime() {
    return System.nanoTime()
}
mdewitt
  • 2,526
  • 19
  • 23
  • that's wrong... System.nanoTime() doesn't guarantee accuracy... doesn't give you the current time. – Alboz Oct 07 '14 at 19:59
  • 1
    The OP doesn't need the current time, they need the length of time the program took to execute. `System.nanoTime()` is very well suited for that. It will use the JVM's high-resolution time source. – mdewitt Oct 07 '14 at 20:04
  • the value returned represents nanoseconds since some fixed but arbitrary origin time (perhaps in the future, so values may be negative). – Alboz Oct 07 '14 at 20:06
  • So if he gets: start=-100, end=-120, time=-120+100=-20 nanoseconds?? – Alboz Oct 07 '14 at 20:07
  • 2
    @Alboz, using `System.nanoTime` is the preferred way to measure elapsed time. Look at this SO answer: http://stackoverflow.com/questions/238920/how-do-i-calculate-the-elapsed-time-of-an-event-in-java They spefically mention the pitfalls of using `currentTimeMillis` – mdewitt Oct 07 '14 at 20:11
  • it seems to respond better, but the very goal of my code was to measure something in hardware (CPU). thus trying to minimize software interference. – Ramin Oct 07 '14 at 20:19
  • @mdewitt edit something on your code, so I can change my vote. – Alboz Oct 07 '14 at 20:27
  • @mdewitt I think you should use the modulus to convert negative values to positive. They suggest it as well. But this is as far as one can go with Java, unless one call C code through JNI – Alboz Oct 07 '14 at 20:32
  • well , seems like this the most accurate way. there doesn't seem to be a perfect way that just lets you see pure CPU performance. accepting this answer. thanks – Ramin Oct 07 '14 at 20:33
  • @Alboz I added a comment suggesting that Math.abs() could be used to account for possible negative values. – mdewitt Oct 07 '14 at 20:34