Home Optimization of long method chain in Java
Reply: 2

Optimization of long method chain in Java

PNS
1#
PNS Published in 2017-12-07 22:22:34Z

Analyzing some pre-existing third-party Java code (which cannot be re-written) in an application, I discovered that it is almost entirely structured on long method chains, of the form

public Object process() {
  // Do some class-specific stuff
  return this.getChild().process();
}

where there is a base class defining the process() method, inherited by subclasses that redefine that method and the getChild() call is repeated at the end.

Multiple such chains are created (branched off) at runtime as a result of conditional blocks, some of which may return relatively early (e.g., after 10-20 "links" in the chain), but most commonly the "length" of the chain is much bigger and can even exceed 100 consecutive method calls, before returning the result.

The application uses this code to process large files, with results changing for every invocation of the top level method, usually once every different line of each file.

So, two questions:

  • What performance implications should be expected from such a design, compared to a "regular" one?
  • Is there any trick to notably improve performance of that code as-is (e.g., by changing some JVM parameter)?
Dave Cousineau
2#
Dave Cousineau Reply to 2017-12-07 23:16:06Z

Method calls are very fast (10s or 100s of millions per second), so make sure it's actually beneficial first by profiling the system.

Otherwise, you can use caching to improve efficiency, especially if your results are consistent (same input, same output).

Ex:

Object cache = null;

public Object process() {
   if (cache == null)
      cache = this.getChild().process();

   return cache;
}

If there's some kind of input or state involved, then you could use a Map for the cache which uses keys of the input value and stores values of the output value.

Holger
3#
Holger Reply to 2017-12-08 16:38:22Z

A statement of the form

return getChild().process();

is not different to

SomeType var = getChild();
return var.process();

In both cases, one method will be invoked after the other and the return value of getChild() will be used as receiver of the process() call.

If you are hunting for irrelevant minor technical details, the first form doesn’t need a local variable. But since in HotSpot, a fixed-size stack memory is pre-allocated on thread creation, it is impossible to perceive any performce difference between these two forms.

The choice between these two forms is purely a stylistic one.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.317967 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO