[java] how do you test for efficiency in java?

Started by
18 comments, last by GameDev.net 19 years ago
I test Java routines by calling System.currentTimeMillis() and compare which set of routines consumes less time. But results are not very consistent. Sometimes they are, more or less, the same, and I can not determine which is really faster. I guess this is not the good way to compare things for efficiency. Is there some other better way? Some tools to use? Please show me?
Advertisement
If you just want something simple, you can stick with the System.currentTimeMillis() idea, but have a loop inside the timed area of your code that runs each routine several (hundred, thousand, hundred thousdand - depending on how long your routine takes) times, then divide the time that it took by the number of loops. I wouldn't count on most clocks to be more accurate (though some are) than about 16 ms +/- the real time, so make sure to run your routine enough times that a result a few ms off won't taint the results.
This give you a good idea of the performance of your app. Try passing -Xprof to the JVM, it will then output the profiling data for your app when it closes.
The most important thing you have to do, and which isn't mentioned above, is to run the test for at least 10 minutes, then pause, then *start counting the time* and run it the X,000 times as mentioned by TBM.

If that annoys you, bear in mind that what you're doing is pretty much a complete waste of your time anyway, and you really shouldn't be doing it. Java is far too advanced for you, and you should just program your code well and worry about performance when your game is too slow. Which shouldn't be until it's nearly complete anyway.
Quote:Original post by davenirline
I test Java routines by calling System.currentTimeMillis() and compare which set of routines consumes less time. But results are not very consistent. Sometimes they are, more or less, the same, and I can not determine which is really faster. I guess this is not the good way to compare things for efficiency.

Is there some other better way? Some tools to use? Please show me?


You could try using System.nanoTime(); instead, which returns the current time in nanoseconds (billionths of a second). I've no idea how accurate this is but i use it anyway and it definitely helps give some idea as to how my programs are performing. It should help give you a better idea anyhow than System.currentTimeMillis() which only returns the time in milliseconds.

I've heard older JRE's have issues with timing also, so make sure you have the latest JRE if you want the most accurate results.
Quote:Original post by Darragh
I've no idea how accurate this is


it's as accurate as the OS allows. That's the definition - partly influenced IIRC by those of us who were upset that currentTimeMillis was inaccurate for no actual reason, and so asked for "somethign that is as accurate as the OS allows".

Quote:
but i use it anyway and it definitely helps give some idea as to how my programs are performing. It should help give you a better idea anyhow than System.currentTimeMillis() which only returns the time in milliseconds.


No, it will make absolutely no improvement whatsoever at all. You should read the AP post above.

Quote:
I've heard older JRE's have issues with timing also, so make sure you have the latest JRE if you want the most accurate results.


Their issues are granularity, hence no effect on benchmarking.
Quote:Original post by redmilamber

Quote:
but i use it anyway and it definitely helps give some idea as to how my programs are performing. It should help give you a better idea anyhow than System.currentTimeMillis() which only returns the time in milliseconds.


No, it will make absolutely no improvement whatsoever at all. You should read the AP post above.



No I didn't mean that it was more accurate in keeping the time.

What I meant was that the greater resoultion of the timer (nanoseconds rather than milliseconds) would help in noticing smaller changes in the speed of his code.

Suppose that a particular function takes less than 1ms to run- using milliseconds in this particular case would not be helpful in detecting any speed improvement...
Quote:Original post by Darragh
Quote:Original post by redmilamber
No, it will make absolutely no improvement whatsoever at all. You should read the AP post above.


No I didn't mean that it was more accurate in keeping the time.

What I meant was that the greater resoultion of the timer (nanoseconds rather than milliseconds) would help in noticing smaller changes in the speed of his code.

Suppose that a particular function takes less than 1ms to run- using milliseconds in this particular case would not be helpful in detecting any speed improvement...


Something that takes less than a millisecond to run is unmeasurable. There are no two ways about this: the fundamental design of java, laid down more than 11 years ago, forces that a speed test is only meaningful when run over the course of minutes. The current JVM's require TEN MINUTES to come up to full "normal" speed, and must be timed for several minutes to get an accurate measurement.

Hence the "run for thousands of times" (amongst several other reasons why you also need to do that - including the fact that on default settings some jvms will not optimize something until it has been executed 10,000 times).

Welcome to Java...
With the Client VM, the compiler kicks in after something is called 1500 times. It's only the server VM that compiles things after 10000 invocations. That is why the Client VM 'feels' much faster than the server VM while the server VM performs better optimizations.
Quote:Original post by redmilamber
Something that takes less than a millisecond to run is unmeasurable. There are no two ways about this: the fundamental design of java, laid down more than 11 years ago, forces that a speed test is only meaningful when run over the course of minutes. The current JVM's require TEN MINUTES to come up to full "normal" speed, and must be timed for several minutes to get an accurate measurement.

Hence the "run for thousands of times" (amongst several other reasons why you also need to do that - including the fact that on default settings some jvms will not optimize something until it has been executed 10,000 times).

Welcome to Java...


Letting the code run for 10 min before doing the test is a bit silly. So what do you do in a real game. Force the player to wait for 10 mins so the vm can warm up. Microbenchmarks must be treated with scepticism and haveing a warm up phase is a good idee, but TEN MINUTES!!!

Mesuring methods can be done if you've got a timer with enough precision. The nanoTime uses the performance counter I think, and could be used to mesure a method. Sure, other treads might step in, the mothod might be compiled etc. But it can be a good indication on how the method is performing.

This topic is closed to new replies.

Advertisement