Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I was working on neo4j graph database in java. To get the reference node of this db:

    GraphDatabaseService graphDb=new EmbeddedGraphDatabase(DB_PATH);

    Node Root=graphDb.getReferenceNode()

I always forget to prefix graphDb when calling getReferenceNode(). So what I did :

   public Node getRootNode(){
   return graphDb.getReferenceNode(); }

Now after doing this , I thought this to be overkill as I am replacing a simple statement with a function call which surely has overhead but using getRootNode seems more intuitive to me.

So my question is am I right in thinking that doing the above mentioned thing is inefficient? Or does it not affect performance that much?

share|improve this question
add comment

8 Answers

up vote 2 down vote accepted

You can also just store the referenceNode in a variable as it is constant per GraphDatabaseService.

You can also declare it as a final instance variable in the constructor of your service to document that.

share|improve this answer
    
wow.... did not think about that :) –  codecool Jul 19 '11 at 11:43
add comment

In modern Java, function calls are practically free. If it is called rarely, you won't notice the overhead. If it gets called frequently, the JIT will inline the call, eliminating any overhead.

share|improve this answer
    
You're probably right. But I remember times when calls to simple getters in loops drastically decreased performance. These were the Java 1.4/1.5 days. –  Falcon Jul 19 '11 at 8:16
    
@Falcon, yes, the first JITs weren't so sophisticated, but they improved greatly since the early days. I can't exactly define which JVM version "modern" above refers to, but my guess is Java 5 and above. –  Péter Török Jul 19 '11 at 8:20
    
@Falcon, sure it wasn't the Java 1.3 days? –  user1249 Jul 19 '11 at 10:00
    
@Thorbjørn Ravn Andersen: 100% sure. I recall an extreme performance gain by removing a simple getter for an image's width/height from a loop header during the Java 1.5 times. I do not know whether I used 1.4 or 1.5, but 1.5. was definitely rolled out then. –  Falcon Jul 19 '11 at 10:04
    
@Falcon: In that particular case there may have been something (such as different overridden implementations of the getter in the class hierarchy) preventing the JIT from inlining the call. I'm pretty sure even the 1.4 JVMs could inline method calls at least some of the time. –  Michael Borgwardt Jul 19 '11 at 10:51
add comment

Think about it again.

1. YAGNI - You ain't gonna need it. Do you really need to wrap the function? How often and in how many places do you resolve a root node - and most importantly - do you expect to add additional behaviour to this method later on?

2. Does it really improve readability? This is highly subjective. In my eyes, both variants are almost equal in readability. I'd even prefer the first one if I don't really need the wrapper because I don't want to add behaviour later on, as it's easier to debug, one less level to step through.

3. Performance This is a minor concern here. I doubt you call that method very often. When you call it in a loop, it could have a severe impact on performance. The overhead itself is negligible for single function calls.

4. Design Decision Do you want to hide the graphDB Member completely, i.e. behind an interface? Then by all means create a whole abstraction of it with all the methods necessary.

That said, the increased readability is highly subjective (in your eyes only) while adding a new layer that could potentially lead to a performance loss. That's fine if you need that wrapper because you expect to add additional behaviour later on and your code is sprinkled wich calls of getReferenceNode(). If you just have a single call or very few calls of getReferenceNode and you don't plan to add additional behaviour later, then I'd not create that wrapper.

share|improve this answer
1  
Performance - I think the work done by graphDb.getReferenceNode() is going to be a lot heavier than what is involved in a single function call, making that argument pretty much moot in a situation like this. –  Michael Kjörling Jul 19 '11 at 8:24
add comment

A classic example of premature optimization. When writing code you must feel free to add all the structure you see fit. Later, a profiler will tell you where you need to optimize.

share|improve this answer
    
if I am gonna use profiler later would not it be a problem to change working code later on and face problems? –  codecool Jul 19 '11 at 11:45
    
Optimization based on Big O Notation (en.wikipedia.org/wiki/Big_O_notation) is the only one that matters also before measuring performance. Any other must be backed by profiling, better if in real situations. –  Ando Jul 19 '11 at 11:54
add comment

Use a profiler to test this. Sometimes, it's better to increase readability if there's not such a great performance penalty.

share|improve this answer
    
never used profiler... can u point to any good profiler for mac –  codecool Jul 19 '11 at 8:05
    
jvisualvm is available in the Java developer package downloadable from Apple Developer Connection (free registration) –  user1249 Jul 19 '11 at 11:11
add comment

This looks to me like the Java equivalent of creating a C/C++ macro to save typing a few letters, which I can't accept as a good practice. You'll be re-reading the code far more often than you will write it, so the "additional level of indirection" you've added will cost far more time in maintenance than you will save in development.

share|improve this answer
add comment

SO my question is am i right in thinking that doing above mentioned thing is inefficient? or it does not affect performance that much?

If you are mostly worried about performance, then put each variant in a separate loop, run through it a million or somesuch amount of times, and measure the time difference between executing the two variants. Chances are the difference will be negligible to nonexistent.

If you look at the byte code, I wouldn't be at all surprised if the entire function is inlined by the compiler, since all it does is wrap another call.

share|improve this answer
1  
Looking at the bytecode is not decisive, since the call will probably be inlined runtime, by the JIT (if at all). –  Péter Török Jul 19 '11 at 8:39
    
That's probably going to depend on the compiler used, too, but actually testing the performance of both approaches should be fairly telling. And easier. –  Michael Kjörling Jul 19 '11 at 9:39
add comment

Do not do this. You are simply renaming the function to fit your personal preconceptions. Some future maintainer will have to learn neo4j, and will know the meaning of getReferenceNode. Then she will see calls to getRootNode and think "getRootNode? WTF is that?" Then she will go read your function, and grab something and throw it against the wall cursing your name. Then she will refactor, inlining getRootNode out of existence.

We introduce functions to reduce duplication and maintenance cost. Your function does the opposite.

Someone made a choice to use neo4j. Learn it and use it as designed.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.