How to optimize and measure the performance of openmrs-standalone application

Hi friends, Recently i have been so curious about about java optimization can be adhered relation to how we can measure openmrs-reference application perfomance, My use case here was to see how i can determine the performance of java codes in openmrs-core, tried to use installed eclipse visualVM but its seems it is not the better tool to use and seems to be taking too much time. Going a little detailed am working on this ticket, which requires optimizing concept class first where neccessary and its related conceptResources class in webservice.rest,

One thing i understand about java optimization is that we need to use stringBuilders not operators and string concatenation, on the other hand depends or its irrational. Kindly advise me of which tool to use to be able to visualise the performance of application such that am able to be at a reproduction level of the bug in the ticket above thanks cc @dkayiwa @ibacher @k.joseph @mozzy

1 Like

hei just looked at the ticket,it requires a work around on a better way of returning concepts so as the process doesnot take much time when in use with android client,this might include things like reducing the iteration etc

Thats optimizing, you are right iteration also can optmize, but am looking it at a perspective as whole from the roots of concept class in core to conceptResource in rest, thanks @herbert24

This is actually based on incorrect advice, or rather, it was true at one point (I think around Java 5) that concatenation using “+” was less efficient than using a StringBuilder, but since that point the Java compiler has been changed so that writing something like:

"This is a test string with a value of " + value + " isn't that great?"

Compiles into the equivalent call using StringBuilders.

Optimization, though, is a hard problem that’s often to the specific operation in question and reducing the time for a query through a web API like this is… unlikely to be a simple task. Conceptually (at least) the web request looks something like this (AC = Android Client, WS = REST Webservices Module, DB = database):

AC sends request to WS WS converts parameters into DB query and queries DB WS takes results from DB and marshals them into JSON format WS sends the JSON formatted response to AC

Since the query is paged, we then have the results:

AC requests next page from WS etc., etc.

Given all these different components the question is where is the slow down? Something like VisualVM might give you and answer to that, but as you’ve noticed, it will do so at the cost of severely slowing down OpenMRS (even if it does work, you’re likely to get a lot of noise as OpenMRS does quite a lot of things).

So one way towards a quick win is to actually look at the PR the original author created. The problem with that PR seemed to be that it only works on OpenMRS 1.11 or newer. So one way to revive that would be to take that code and see if it can be reworked so that it applies to OpenMRS versions 1.11 or newer (or at least to identify the version at which it could be applied).

Another thing to look at is precisely what information does the Android Client need about concepts? Can we somehow limit down the set of data that it needs supplied from “everything” to something slightly smaller? Would it make sense (for instance) to allow the Locale of the concepts to be specified as part of the query (if it isn’t already) and only return concept names that matched a specified locale? Does the Android Client request specify that it only needs concepts that are not retired?

1 Like

Haa i meant using stringBuilders are much efficient than operators like string concentation, i hope i was right

Thanks for this description, its amazing :+1:

Another big thumbs, you brought it in a broad way, it makes alot of sense and diverted my thinking from this thanks @ibacher

It’s a bit of a mixed bag on String concatenation:

"This is a test string with a value of " + value + " isn't that great?"

Will likely be just as performant as:

new StringBuilder("This is a test string with a value of ").append(value).append(" isn't that great?").toString();

And is much easier to read. But on the other hand:

String[] typesOfBeans = new String[] { "chickpea", "fava", "lima", ... };
StringBuilder sb = new StringBuilder("My favourite beans are:");
for (String bean : typesOfBeans) {
    sb.append("\n").append(bean);
}
String message = sb.toString();

Is substantially better than:

String message = "My favourite beans are:"
for (String bean : typesOfBeans) {
    message += "\n" + bean;
}
1 Like

Thanks @ibacher for a detailed info.According to the ticket above, the ticket reporter needs to report back if this can also be implemented and give us a detailed information , am trying to play around with code but it would be more of help if i can reproduce this on android client.