Java macros similar to C++ macros?

Hello,

I recently stumbled over various situations where I wished that I had some kind of macros like I’m used to from C++ times. When I enter the title of this thread and follow the first few links I’m not finding a good solution. I hoped to find a plugin for an IDE (jME SDK / NetBeans) and also did a quick search for that - but no result. I also must admit that I’m not a NetBeans expert (only recently learned several refactoring options and the regex search - which is really great).

Maybe someone here has a hint?

I currently need this for these two things:


thing #1 "DEBUG mode"
solution for now: “DebugConfig” is my custom singleton class for all my libraries

if( DebugConfig.get().isDebugging() ) { /* Debug logic */ };

or

if( DebugConfig.get().isDebugging( Package forThisPackage ) { /* Debug logic */ };

or

if( DebugConfig.instance.debugOn ) { /* Debug logic */ };

The third alternative is the fastest (no function calls, but perhaps access to a distant memory location everytime this static ‘instance’ variable is accessed). Also the ‘instance’ variable can not be final because I want the user to be able to give a custom DebugConfig subclass for the ‘instance’ variable - which might prevent further JIT compiler optimizations.

The “Debug logic” mainly is there to check data for validity and to write some human readable output to the logger if any check fails. This code will not be needed when the Debug phase is over.


thing #2 "Code duplication / redundancy"
Here is an example:

@Override
public String generateName(String inputString, CanGetProperty propertiesSource) 
{
    if(inputString == null) return null;
    if(propertiesSource == null) return null;
    String result = civMode.makeCaseInsensitive(inputString);
    if(!quickCheck(result))
        return result;
    return generateNameStep(result, propertiesSource);
}

@Override
public String generateName(String inputString, CanGetProperty... propertiesSources)
{
    if(inputString == null) return null;
    if(propertiesSources == null) return null;
    String result = civMode.makeCaseInsensitive(inputString);
    for(CanGetProperty propertiesSource : propertiesSources)
    {
        if(!quickCheck(result))
            return result;
        result = generateNameStep(result, propertiesSource);
    }
    return result;
}

@Override
public String generateName(String inputString, Set<CanGetProperty> propertiesSources)
{
    if(inputString == null) return null;
    if(propertiesSources == null) return null;
    String result = civMode.makeCaseInsensitive(inputString);
    for(CanGetProperty propertiesSource : propertiesSources)
    {
        if(!quickCheck(result))
            return result;
        result = generateNameStep(result, propertiesSource);
    }
    return result;
}

@Override
public String generateName(String inputString, Iterable<CanGetProperty> propertiesSources)
{
    if(inputString == null) return null;
    if(propertiesSources == null) return null;
    String result = civMode.makeCaseInsensitive(inputString);
    for(CanGetProperty propertiesSource : propertiesSources)
    {
        if(!quickCheck(result))
            return result;
        result = generateNameStep(result, propertiesSource);
    }
    return result;
}

The code in the second, third and fourth method is identical. I could make an array or Set and then just call one of these methods and the other two just relay to that single implementation, but then I will need to create a temporary container (array or Set) and fill it - which costs some time. I used this technique in other places and just lived with it. Usually I don’t write code twice and live with a moderate performance loss, but maybe this is not needed?

Well, maybe someone has a good idea or knows a NetBeans plugin or other trick which is perfect to deal with such situations? :chimpanzee_sad:

As to the first, macros are sort of anti-java. A method call is not really going to cost a measurable amount more than a field access, especially if it is a final method. Every Java log implementation in existence does it this way.

As to your other, you already have two redundant methods that you can immediately delete with no consequences. The first one that takes a single CanGetProperty is redundant in face of the … one. The Set-based one is redundant in the face of the Iterable one. You can delete those two right now with no change in functionality at all other than one extra array access in the first case. Do not be concerned about that waste really, especially not in this use-case. It’s the worst kind of micro-optimization.

Now, once you’ve done that, you can reduce the new first one down to:

@Override
public String generateName(String inputString, CanGetProperty... propertiesSources)
{
    return generateName(inputString, Arrays.asList(propertiesSources));
}

This is a thin lazy wrapper and costs almost nothing.

Macros often turn out to be the worst kind of programming. Java doesn’t include them and we are all 99% glad about that.

2 Likes

Note: fields do not override… so you need a method if you want the user to be able to override. Way easier just to support some kind of configurability, ie: just let them set the value.

There are some ugly things like Java+ and other preprocessors. But from my experience it’s almost always better to think a bit more about architecture than to have to deal with “overmacroed” code later.

3 Likes

Yes, that’s already the case in my code. The user can swap in an own custom subclass. Both mechanisms (getter call and direct access to ‘instance’ variable work with that). Thanks for the hint.

To the other thing:

First of all: Thank you for your comments. I needed to hear that from an experienced Java developer.

You are right - maybe micro optimization is not the right way (at least for the second “generateName thing” - because the String operations are way more costly than anything else going on in these methods).
I usually do things like you said and relay all to one method. Depending on the implementation of Arrays.asList this will be quite fast, because like you said “thin wrapper” (like Collections.unmodifiableSet etc.).

I did some tests with the DebugConfig micro optimization a few weeks ago and it gave me 5% performance boost on my machine when using direct access to the ‘instance’ variable. And for other problems like integer parsing I could achieve huge boosts using micro optimization. So it’s not always that unimportant.

The next big micro op stuff will be GPGPU (OpenCL or something like that). Still a world to be discovered by me. I’m amazed by the Blender renderer which already lets me decide wether to use CPU or GPU and gives me around half the rendering time when using GPU for rendering a poster image. Many of the things I want to achieve in my “next big thing” might get even better boosts because of the nature of that thing…

Why do you allow subclasses when a setter would be fine? Then your methods could be final.

I seriously doubt that any test that showed a 5% difference between a method call and a field call is valid. Even a program that only called a method or a field would likely have a hard time achieving that much difference.

My guess is that something else was at play or you make WAY too many calls to your debug check.

Yes, it was a stress test that only called debug code logic. Some million or billion times. Don’t know anymore - each test was around 7 or 8 seconds and multiple starts via NetBeans and I used the high performance timer.
Of course, that’s unrealistic behavior because no programm is likely to call only debug code and nothing else… :chimpanzee_closedlaugh:

I thought that I need subclasses for something like:

if( DebugConfig.instance.debugOn ) { /* Debug logic */ };

I started with an interface which doesn’t allow that as far as I know - so I switched to subclassing.
Does using final methods give a performance boost? Hm … maybe then I should switch back to an interface and leave my current code like it is now:

if( DebugConfig.get().isDebugging() ) { /* Debug logic */ };

Thanks both for your comments and ideas so far,

If all you care about is logging, you could take advantage of the java logging API. If you call

logger.log(Level.DEBUG, "yadda yadda: {0} ", someObject);

The someObject.toString() method will be called only if DEBUG is enabled, otherwise is ignored and the cost is negligible because no strings were concatenated. You can put all your heavy string building inside the toString() method.
You don’t need to branch, call the method every time, the logger already has the logic.
The advantage of this is that all your debugging logic is kept in the binaries and you may ask your users to enable logging for troubleshooting for instance.

1 Like

I think the whole concept of making a caller subclass a class just to provide some custom logic is a bit strange, personally. Just let them set the field through a setter. Why make them subclass? It’s kind of abusing inheritance… which you generally should only use as a last resort.

Furthermore, I think using an interface will negate any benefits of the ‘final’ method but maybe not. Hotspot may still inline them I guess.

It’s funny that logging frameworks have been doing this differently for a very long time with really good results. You might just mimic what they do… or even just use it depending on what you are using this debug stuff for.

if( log.isDebugEnabled() ) {
    // do some debugging stuff
    // log the debugging stuff
}
2 Likes

Yes, I’m abusing inheritance willingly to get the 5% extra performance via direct attribute access.
Not very high level thinking (more the “anti” of high level), maybe that’s a bad thing at all.
I should just keep things as they are now (using two getter calls instead of two direct attribute accesses).

Thanks, I will look for that. Maybe learn a bit more about Java Logging API.
Currently I’m just following the simple pattern of giving each class its own logger like this:

//logging API
private static final Logger logger = Logger.getLogger( FontCollectionImpl.class.getName() );

And then in the end I’m using that logger with Levels like INFO, WARNING, ERROR.
Not the smartest solution maybe, but it works for now.

Based on your earlier response, this is an entirely bogus number as it was 5% of a stress test that ONLY called that code. In your actual app this will be less than 0.01 %… I’d be surprised if it was measurable at all.

You ultimately gain nothing but pain with this approach.

That’s exactly the way you should use logging. And that’s exactly the way you could do debug mode. Logging internally is checking a field to decide if things should by logged or not.

I don’t know what you are doing with your ‘debug code’ but it sounds to me like earlier slightly misguided decisions were made that logically led you down a path to crazy town.

1 Like

It’s not that crazy. You already said what I need:


Actual use case: When I'm in "debug mode", I will validate input data and log warnings or throw exceptions depending on the state of the input data (content of the file might not be okay and a check needs a lot of time). At a later phase (when a game is ready for release) the Debug is turned off and every data is swallowed without any validity checks:
Implementation ideas: ? Like you suggested, I could also ask the logger of each class what Level it currently has. I wanted a more global switch (one for whole program). Perfect would be a switch for each library or package, not only the whole program. Those things led to the decision of a global switch or package-wise switch.

→ You’re right, if these things already exist in Java, then I should investigate those solutions
→ I wanted to get some suggestions for this problem in general. That’s why I posted this:

EDIT: This “global switch” is exactly what the C++ macros typically achieve with #ifdef DEBUG blocks for the precompiler - the DEBUG is either true or false depending on the configuration of the IDE or compiler in that IDE (e.g. Visual Studio has some buttons for that similar to NetBeans).

→ I simply need a good idea how to achieve a smart solution which also is easy to manage

Hm, I could not find “Level.DEBUG”, I only found this: Level (Java Platform SE 8 )

The idea with the new logging interface is nice. Only annoying thing of that new system is that I can’t use single quotes (’) anymore because they are being replaced by (’)(’) (two single quotes). I have lots of single quotes in many of my logging messages and started to return to the older logging interface some time ago. → Now I see what a big advantage the new system has to offer - Thanks for that precious hint! :chimpanzee_smile:

Yeah, sorry about that, I don’t usually use Java logging, I use SLF4J that’s kind of the same thing. Logging in java is such a mess.
But you got the idea, if the logger is disabled for that level, the string won’t even be generated and it’s just a method call that does close to nothing.

1 Like

Sounds like you are partially reimplementing asserts.

1 Like

Ah … of course … I knew that assert statements can be deactivated via runtime config (unlike AssertionErrors - which can not). One could use something like…

boolean testDataFunction(theData){ /* test the data */ }

and

assert(testDataFunction(theData));

Did not think of that before - thanks for the hint… :+1:

The complex thing with my stuff is that I can sometimes have partially invalid data and that this might even be desired by the user. I call that “the Frankenstein mode”. Because it lets you compose data from bits and pieces and at the end you either have a living creature or yet again invalid data. :chimpanzee_smile:

This. Can’t be overstated.

@Ogli try to use “Strategy” pattern or maybe “Template method” pattern, looks like it will suit good for your usecase.

1 Like