Can the program below be re-written so that the format string is parsed only once?
In my application, I'm using String.format to format output for a report of thousands of rows of data with some number of columns. String.format is used for each column, so say there are 1000 rows by 5 columns, String.format is called 5 thousand times.
When the report size is 'large', the application slows down. Taking a look, I found that the application is constrained by memory. When the report size is 'large', the application is spending much cpu time in garbage collection. Enlarging the jvm's max memory is not an option because there is not enough ram to accommodate the necessary size. So, I run the application under yourkit memory analysis. I find that much of the collection is on memory allocated by String.format.
I am unable to post the actual code of the application. Here is a simple program. It demonstrates the undesired memory allocations:
public class FormatPerf {
public static void main(String[] args) {
for(int i = 0; i < 30000; i++) {
doFormat("abc", "def", "ghi", "jkl");
}
}
static void doFormat(String w, String x, String y, String z ) {
String.format("%s%s%s%s", w,x,y,z);
}
}
yourkit is showing that the 97% of GC'ed memory is allocated by String.format in this program. In real terms, that is 53MB.
yourkit shows a stack trace of String.format, and reports the allocation for each callee. Formatter.parse is allocating the entirety of that 53MB. I assume 'parse' is 'compiling' the format string.
Assuming that the result of Formatter.parse is the same for every call, then it need only be called once. In the program above, its being called 29,999 times more than necessary. If the call to parse can be constrained to be made only once, then there would be a huge memory saving. Each call to parse uses (53MB/30K) 1.7KB.
Can the program above be re-written to constrain 'Formatter.parse' to run only once?
If you suggest an alternative, use of a format string as defined in the Formatter api documentation is strongly preferred.
Thanks.
John