akappa
akappa

Reputation: 10490

Overhead of searching and calling a method with reflection

I have a class that should read a message, extract its type from the envelope and then call a method that have to process the message; at each message type is associated an enum member.

There are 30+ message types.

One way to dispatch the message is to just use a switch, but it's really ugly and error-prone (have I already tract that case? have I tract that case two times?).

One another way is to define an interface with a single method process(data) and create one class for each message type that implements that interface, register those classes with a map and, in the code that should process the message, just call map.get(messageType).process(data); but it's really annoying to create 30+ classs.

One another way is to use reflection: define one function for each messagetype, with a precise signature and pattern name, like processMessagetype; then create a map from messagetype to Method (filled with a simple search upon getDeckaredMethods()) and then do something like: map.get(messageType).invoke(this,data).

What method you should use? What's the overhead of using java's reflection?

Upvotes: 1

Views: 1386

Answers (5)

GuyBehindtheGuy
GuyBehindtheGuy

Reputation: 1368

I'm going to guess since you're talking about "messages" and "envelopes" that you're passing these messages over the wire. The time it takes to do that will absolutely dominate the extra time it takes for reflection. I've used reflection like this, and it's not a bad model.

Upvotes: 1

Gustavo Muenz
Gustavo Muenz

Reputation: 9552

Reflection has a big overhead if you're looking for good performance. If your routine (message dispatch) is going to be used over and over the polymorphism alternative is better. Also, IMO it's better if looking in a OO perspective, since as stated by Brian on his answer, it's easier and cheaper for maintenance.

Your clas handling 30+ messages can easily grow to 100+ messages, then you will have a class with 100+ methods, add the private methods too and code reuse will be hard and your class has just became a mess.

The overhead of reflection over polymorphism and switch is something like this:

time spent on a switch case call: 1
time spent on a polymorphism call: 1.1
time spent on a reflection call: 1.9-2.0

I benchmarked these guys a while ago, and those were my results, I don't have the code now because these benchmarks were done on my previous company and I don't have access to that code anymore.

Upvotes: 4

Tom Hawtin - tackline
Tom Hawtin - tackline

Reputation: 147164

You could add the process method to the enum.

What exactly is wrong with a big switch (with each case just calling a method)?

The major cost of reflection is that it tends to make code suck. ;)

Upvotes: 2

matt b
matt b

Reputation: 139931

I would think that the first method/algorithm you described (a Map of message type to class) would be easier to manage over time with updates, maintenance, etc.

The second pattern you describe would basically involve having a class with about 30+ methods in it, correct? That would be quite a pain to manage over time.

Does each message type require truly unique processing logic? By creating implementations of an interface to process the message, you could probably benefit from a type hierarchy, i.e. a superclass that can handle parsing a certain family of messages, and then you just have to override it in areas where messages of that family differ...

Upvotes: 0

Brian Agnew
Brian Agnew

Reputation: 272297

You don't say what your process() method is going to be doing, but I would be surprised if any overhead in dispatching a method call is going to be at all significant.

I would make the language and OO system work for you, and create an interface/abstract base class with the appropriate method implementation(s).

Remember that premature optimisation is the root of all evil (Knuth)

Upvotes: 1

Related Questions