please could you provide a concrete example of why you are trying to do this, as I am completely stumped about what you are trying to achieve.

instead of calling the method that has been written in the code, you want to call another method completely?
so instead of calling Wendy.hello() you want to call fred.confused()
but you want this being controlled at runtime not in the code?
couldn't you just..

Wendy Gibbons wrote:please could you provide a concrete example of why you are trying to do this, as I am completely stumped about what you are trying to achieve.

instead of calling the method that has been written in the code, you want to call another method completely?
so instead of calling Wendy.hello() you want to call fred.confused()
but you want this being controlled at runtime not in the code?
couldn't you just..

the if-else style would certainly resolve the issue... and this really is something which I want to achieve but not with the use of the if-else construct itself.
As a concrete example... I would like to suggest the usage of log4j API.
We heavily use this API in our code for logging purposes. And as you might be aware... we can control the level of logging as debug/info/warn/error etc.
This can be done by specifying the level in log4j.properties file.

Now suppose we've set the level to info/error... but there would be a lot of debug calls present in the code.
In such cases, even though the debug logs would not be printed, but the calls themselves are entertained and only inside the method is it checked whether the log is to be printed or not.

For such cases I would like to bypass the call itself if the level is not debug. This can be done with if-else but that is not a feasible solution when we have a lot of debug statements present in the code.

Anupam Jain wrote:...there would be a lot of debug calls present in the code.
In such cases, even though the debug logs would not be printed, but the calls themselves are entertained and only inside the method is it checked whether the log is to be printed or not.

For such cases I would like to bypass the call itself if the level is not debug.

Why do you want to do this ? Have you seen that the the calls are causing a performance problem or are you just assuming that they will ?
Unless there is a demonstrable performance problem due to these calls then you shouldn't worry about them.

Joanne Nea wrote: Why do you want to do this ? Have you seen that the the calls are causing a performance problem or are you just assuming that they will ?
Unless there is a demonstrable performance problem due to these calls then you shouldn't worry about them.

There definitly is a performance hit with all these call present in the code when the logs aren't actually getting printed.
For example let's say we have a logger call as follws :

Now even when the logger level is not debug, this statement would cause the String object creation and then appending the value of var to occur.
I guess you've got my point.

Anupam Jain wrote:There definitly is a performance hit with all these call present in the code when the logs aren't actually getting printed.
For example let's say we have a logger call as follws :

Now even when the logger level is not debug, this statement would cause the String object creation and then appending the value of var to occur.
I guess you've got my point.

There certainly is some overhead, but you'd need to profile your application to know whether the overhead is actually causing some problems. See also "premature optimization".

I've personally resolved this issue by implementing my own logger (it calls log4j in turn, of course). The important part is here:

The message is passed to the logger as a String plus an array of references (causing an overhead I'm really not going to care about), and is formatted only when the logger is active. Regardless of how expensive the logged object's toString() method is, it is evaluated only when needed.

Note: I'd like to make findbugs check the formal parameters of the debug method in the same way it checks the String.format() invocations, but I didn't find time to delve into the modifications yet.

Anupam Jain wrote: There definitly is a performance hit with all these call present in the code when the logs aren't actually getting printed.
For example let's say we have a logger call as follws :

Now even when the logger level is not debug, this statement would cause the String object creation and then appending the value of var to occur.
I guess you've got my point.

So, you're assuming there will be a performance hit.

In my experience, there rarely is, and on those few occasions where it happens (like where the object whose toString() method you're calling is a deep object graph with lots of other toString() calls), it's not much of a burden to surround it with if/else.

Having said that, however, I've long wished that logging tools would provide debugf(), infof(), etc. methods similar to printf():

Then, the "f()" method would check the level before calling String.format(), thus deferring the expensive call until we actually need it, and skipping it if we don't.

I actually write such a logger not that long ago. It was a bit of a challenge figuring out how to get the wrapped logger to log the proper class and line rather than the line of my delegating logger.

Anupam Jain wrote:There definitly is a performance hit with all these call present in the code when the logs aren't actually getting printed.
...
Now even when the logger level is not debug, this statement would cause the String object creation and then appending the value of var to occur.
I guess you've got my point.

Yes, but, as with almost every question about optimization, I suspect you're concentrating on the wrong thing (see my quote below).

On my 4-year old clunker Dell, your example expression takes 250ns to execute (average over 10,000,000 calls). I wouldn't be at all surprised if a single write to an actual log isn't measured in milliseconds.

Jeff Verdegan wrote:Having said that, however, I've long wished that logging tools would provide debugf(), infof(), etc. methods similar to printf():

Amen.

Winston

Isn't it funny how there's always time and money enough to do it WRONG?
Articles by Winston can be found here

Martin Vajsar wrote: I've personally resolved this issue by implementing my own logger (it calls log4j in turn, of course). The important part is here:

The message is passed to the logger as a String plus an array of references (causing an overhead I'm really not going to care about), and is formatted only when the logger is active. Regardless of how expensive the logged object's toString() method is, it is evaluated only when needed.

Note: I'd like to make findbugs check the formal parameters of the debug method in the same way it checks the String.format() invocations, but I didn't find time to delve into the modifications yet.