3

Suppose I have some code, and I want to optimize it to the maximum, disregarding readability, maintainability, etc.

For this purpose, is there anyway to figure out how much time every basic action takes? I suppose this may be CPU dependent, but I'm not sure.

I mean stuff like cycling through a for, assignments a=24, mathematical operations 2+25, etc.

9
  • Then how do I know how much time System.nanoTime() takes? Surely this will add quite a bit. Commented Mar 23, 2016 at 2:04
  • He means between two instruction using the current time in nano seconds you could get the execution time. Commented Mar 23, 2016 at 2:05
  • @BenoitVanalderweireldt Well, suppose I do System.nanoTime(); 2+25; System.nanoTime(); then, if nanoTime took 0s to complete, I could know the time taken to perform 2+25, but this carries the time taken to perform System.nanoTime() aswell. Commented Mar 23, 2016 at 2:07
  • Use a profiler. Commented Mar 23, 2016 at 2:17
  • 3
    You can't. That "line of code" is translated into bytecode, which could be executed several different ways during a single launch of a program. Commented Mar 23, 2016 at 2:23

2 Answers 2

7

Context matters. There aren't fixed costs for various Java language constructs that you can just add up to get even an approximation of a useful run-time estimate. The answer you seem to be hoping for doesn't exist.

Even if you did manage to correctly design a microbenchmark to measure some if()s vs. a switch, for example, the results would be heavily dependent on the surrounding code, the details of what the cases were, and the predictability of the branch. Making microbenchmarks is hard. You often end up measuring something other than what you intend to, unless you look at the machine instructions that actually run in your loop. It's also easy for a good compiler to optimize away your loop if you don't use the results, but then it's hard to use the results in a way that doesn't create more overhead than what you're trying to measure.

A good JIT-compiler JVM should generate machine code that's not too much worse than what you'd hope for, so if you have a good sense of how C compiles to ASM, that could be useful for java.

If you want to learn what is fast vs. slow on modern x86 microarchitectures, have a look at Agner Fog's guides.

A good profiling tool can help you figure out whether your code is CPU-bound or bottlenecked on memory (cache misses: memory bandwidth or latency), or branch mispredicts. I haven't done this for Java, but the standard tools (like Linux's perf) probably work as long as you use a long enough run to hide the overhead of the JVM startup.

Sign up to request clarification or add additional context in comments.

Comments

0

You could do something like:

long startTime = System.currentTimeMillis(); // ---- Your code ---- long endTime = System.currentTimeMillis() System.out.println("The previous line took " + (endTime - startTime) + " ms"); 

2 Comments

Won't both calls: System.out.println; System.currentTimeInMillis add a fair bit of time between the completion of the previous lines and the output?
If you want to be more accurate you could use more fine-grained time measure like nanoTime.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.