Performance of parameter object vs long parameter list

444 Views Asked by At

I understand the reason for using a parameter object when it comes to handling methods with long parameter lists. But I have a situation where I would like to reduce the memory footprint of my code.

The question I have is from a performance perspective. How much benefit would I get by going to a long parameter list?

The use case is that these methods will end up being called thousands of times and every time a call is made, a new parameter object is created. I want to really avoid creating all those parameter objects.

Is there a "I can have my cake and eat it too" solution of encapsulating the parameters and only using stack storage?

Unfortunately there are multiple methods in the call chain needing all those parameters, and I don't mind making this change since these methods are not public. Just wanted to know of a better performing solution.

Making this change will impact a large portion of the code and will take a lot of my time. Just want to check if this is a worthwhile change to make before I take this route.

Data structure

The data structure is an object graph. The objects are the business data and the edges connecting them are the calls. These edges are associated with the parameter data. Using parameter objects is beautiful and my code works very well. But I am not satisfied with the performance and want to improve it.

I have profiled my code and these objects are one significant part of the memory overhead. I doubt if they contribute much to the CPU overhead, but am definitely concerned about memory.

This data structure will be part of a framework that will be used in a highly concurrent environment. So reducing memory footprint is of utmost concern to me.

The parameter object has about 10 fields and some behavior associated with it. I can always encapsulate the behavior alternatively.

4

There are 4 best solutions below

0
On

Depends on your situation. The chief issues with object creation (in resource-lacking environments) are memory consumption, and object creation time.

In most cases, object creation time is a snap if you don't have numerous nested objects. For memory cost, count up the number of primitives and multiply them by their respective memory cost, then add eight bytes for the object itself. (And of course do this recursively for any contained objects.)

For the case of Strings, it's roughly (40 + 2*character count) bytes. This is obviously subject to change, but not dramatically. For basic arrays, multiply the primitive cost by the capacity, then add sixteen.

O-notation of creation is basically the O-notation of your constructor. I'm sure there's a little overhead, but it's nothing significant. For a simple parameter object, it's probably inconsequential.

Not to crowd your schedule, but the best possible approach, if efficiency is that important and the answer isn't obvious, is to run benchmarks on both approaches.

As I said, I don't know your exact situation. However, I've solved similar problems in the past with intelligent deviations on the Factory pattern. However, that would require yet another class, and it sounds like that is an issue for you.

2
On

There's a number of techniques.

If you are worried about memory overhead, you can create a fixed pool of parameter objects, and then clear them out when they are released to the pool. That way you fetch a parameter object from the pool, set the values (which I hope are primitives) and then pass it along. Once done, you relinquish the parameter object to the pool which then permits it to be reused.

Keep in mind that object creation in Java doesn't have the same performance as object creation in C++ or other languages (where objects are typically very expensive to create). In some cases, additional objects don't cost much if anything at all, due to JVM optimizations a single object creation often mallocs the memory needed to support half a dozen or more 'new' invocations.

Finally, as to using stack storage, there is support for "stack storage" of objects in Java, but to keep it in line with the language design, it is done at the JVM's bequest and has the same presentation in the code as heap stored objects. I'm not fully familiar with the techniques one would use to get their objects poised for possible stack storage, but I do know that you couldn't guarantee it.

3
On

The question I have is from a performance perspective. How much benefit would I get by going to a long parameter list?

There are a variety of reasons for avoiding long parameter lists, all of which are expounded in the treatment of the Builder pattern in Effective Java, 2nd Ed.

If your method is part of an internal class that will be used and maintained only by you, then there is probably no harm in going with many parameters. But there are some facts to keep in mind. Long parameter lists:

  • make your code very much harder to read
  • can increase the likelihood of difficult-to-debug errors, esp. if the list contains multiple parameters of the same type that can be inadvertently transposed
  • cause your program to be difficult to maintain
  • can doom your API if the method is exported to clients who will be unable to use the method without frequent access to documentation

The fact is that the impact of optimizations (such as telescoping parameter lists) is frequently and commonly overstated. Yes, the JVM will shave some cycles off the execution of a method using the telescoping pattern ... but consider that if that method comprises less than 10% of the total CPU processing of your whole project (common), then the optimization is worthless.

"First make your program correct, and then ... and only then ... make it fast, but only if profiling indicates that you need to."

In fact, the optimization relative to the many benefits of, say, using a builder pattern on a bundling object for a method that needs lots of parameters can be expected to cause you to lose time and money.

The use case is that these methods will end up being called thousands of times and every time a call is made, a new parameter object is created. I want to really avoid creating all those parameter objects.

For modern JVMs, the processing time used for creating and garbage collecting short-lived lightweight objects typically outperforms object pooling.

Your concerns are valid, but you really need to perform profiling to see if there is a memory or performance reason to do an optimization. This is especially true if the cost of the optimization may cost you in other ways down the road (maintainability, readability).

0
On

After further investigation this is what I found.

Replacing parameter objects with long parameter list is not going to improve performance unless the following is true

The parameter objects are not held longer than necessary in the memory

What I learnt from this exercise helped shed light on the object lifecycle of the parameter objects

It helped ensure that the parameter objects were indeed short lived and not shared in other parts of the code unnecessarily. I had to do a little bit of refactoring to ensure this and I ended up keeping the parameter objects.