I was given a weird task. I have to refactor certain methods in a huge code base (the easy part) and provide performance gain reports. I should focus on speed of execution and memory usage. They want know the performance improvement by method!
So I have a method like this:
public void processHugeFile(File f) {
long start = java.lang.System.currentTimeMillis();
// lots of hashmaps, lots of arrays, weird logic,...
long end = java.lang.System.currentTimeMillis();
logger.log("performance comparison - exec time: " + (end - start));
}
Then I have to refactor it:
public void processHugeFile(File f) {
long start = java.lang.System.currentTimeMillis();
// just lists, some primitives, simple logic,...
long end = java.lang.System.currentTimeMillis();
logger.log("performance comparison - exec time: " + (end - start));
}
In the end I just have to process the logs.
But what about memory usage? I have tried getRuntime().totalMemory() - getRuntime().freeMemory() and the getHeapMemoryUsage().getUsed() but they don’t seem to work. Also, JVM Profilers focus on objects not on methods and I am speaking of a fairly large code base.
Can someone provide me some hints?
Thank you very much.
Broadly, refactoring is not a means to increase performance, but to improve readability and maintainability of a code base. (Which may then help you make optimizations and architectural changes with more confidence and ease.) I assume you’re aware of this, and you mean that you’re trying to clean up some slow code in the process.
This is really a tool for a profiler, not for hand-instrumentation. You will never get precise measurements this way. For example,
System.currentTimeMillis()calls add their own overhead and for short-lived methods could take longer than the method itself.Runtimecan only help you get a crude picture of memory usage.I don’t agree that profilers can’t help. JProfiler for instance will happily graph heap size over time, include generation sizes. It will break down memory usage by allocation site, object type. It will show you performance bottlenecks by inclusive/exclusive time. And all of this without touching your code.
You really, really want to use a profiler like JProfiler, not hand-coded stuff.