Search code examples
javaprivateprotected

Performance vs Design related to private/protected methods in java


We're having a discussion with a friend concerning java code design and efficiency.

He argues methods should preferably be private for performance reasons as well as class consistency protection when overriding.

I argue methods should preferably be protected for complete customizability, and to avoid loosing time modifying and releasing an API as soon as its user want to change part of its behaviour.

We know the preference for composition over inheritance so here I mainly focus on performance comparison.

A simple test (see below) proves extended classes with parent having protected methods aren't slower than those with parent having private methods. It's even sometimes (I don't really understand performance change) faster.

elapsed:8051733.063 microseconds for A (private)
elapsed:8036953.805 microseconds for B (protected)

Do you think the below mentionned test is robust enough for making the comparison?

public class VerifPerfProtected {
public static void main(String[] args) {
    int ncalls = 1000000000; //10^9
    ChildrenClassA a = new ChildrenClassA();
    ChildrenClassB b = new ChildrenClassB();

    long start = System.nanoTime();
    a.manyCalls(ncalls);
    long stop = System.nanoTime();
    System.out.println("elapsed:" + (stop - start)/1000.0 + " microseconds for A (private)");

    start = System.nanoTime();
    b.manyCalls(ncalls);
    stop = System.nanoTime();
    System.out.println("elapsed:" + (stop - start)/1000.0 + " microseconds for B (protected)");
}

public static class ParentClassA{
    public void manyCalls(int n){
        for (int i = 0; i < n; i++) {
            callAmethod();
        }
    }
    public void callAmethod(){
        aPrivateMethod();
    }
    private void aPrivateMethod(){
        int a=0;
        for (int i = 0; i < 5; i++) {
            a++;
        }
    }
}

public static class ParentClassB{
    public void manyCalls(int n){
        for (int i = 0; i < n; i++) {
            callAmethod();
        }
    }
    public void callAmethod(){
        aProtectedMethod();
    }
    protected void aProtectedMethod(){
        int a=0;
        for (int i = 0; i < 5; i++) {
            a++;
        }
    }
}

public static class ChildrenClassA extends ParentClassA{        
}

public static class ChildrenClassB extends ParentClassB{        
}
}

Solution

  • It is best not to confuse good design with performance requirements.

    You should start with what is good design, and where you can't agree, you have to both accept it probably doesn't matter. Trying to use a performance comparison to find some measured way of choosing the difference is almost always a mistake because you don't know if the performance difference will matter anyway.

    I suggest you allow for each developer to follow their own style unless there is a very good reason which can be agreed, not to do something.