Sharing primitive data among methods?
<p>Say we have a public method "method," which uses private "subMethod1" and private "subMethod2" in its calculation.  These subMethods serve no other purpose than to break down "method" into more readable, encapsulated sub-parts, and to avoid code duplication within method.  </p>

<p>We need each of these sub methods to operate on 2 or more primitive data types, which are local variables defined at the top of method.  We cannot pass them into the sub methods by reference, since java does not allow primitives to be passed by reference.</p>

<p>So our solution is to refactor, and change the local variables defined at the top of method to member variables, which can of course be read and written by both method and its sub-methods.  The problem is that now we have member variables that don't really exist to store object state, but only exist, effectively, during the execution of method.  Of course, in actuality they exist throughout the whole lifetime of the object, but they are only ever used during the execution of method, and they could vanish at other times without affecting the behavior of the object at all (keep in mind that method initializes the members to default values at the beginning of its method body).  </p>

<p>Well, you say, just wrap the primitives in objects, keep them local within method, then have "method" pass those objects to its submethods, where they will be able to change its value since it was passed by reference as all objects are.  The problem is that "method" is used inside a simulation loop, where it will be run millions of times.  The object wrappers slow things down noticeably, and performance is key here.</p>

<p>So my question is: Is there any solution that will give me the same performance as my ugly "use members to share primitive data between methods" solution, but will also have good OO design?  Would an inner class wrapping the method, sub-methods, and primitive data be appropriate?  </p>

<p>Thanks, 
Jonah</p>

<p>EDIT: Here is a cooked up code sample whose sole purpose is demonstrate the slowdown caused by using object wrappers, as described above:</p>

<pre><code>public class TestSharedMembers {

protected int m17Multiples;
protected int m23Multiples;

public int methodPrimitive(int i) {

    m17Multiples = 0;
    m23Multiples = 0;

    calc17Primitive(i);
    calc23Primitive(i);

    return m17Multiples + m23Multiples;
}

private void calc17Primitive(int i) {
    if (i % 17 == 0) 
        m17Multiples++;
}
private void calc23Primitive(int i) {
    if (i % 23 == 0) 
        m23Multiples++;
}



/// using object wrappers
class IntWrapper {
    private int mInt;
    public IntWrapper(int i) {
        mInt = i;
    }
    public int getInt() {
        return mInt;
    }
    public void increment() {
        mInt++;
    }
}
public int methodObject(int i) {

    IntWrapper o17 = new IntWrapper(0);
    IntWrapper o23 = new IntWrapper(0);

    calc17Object(i, o17);
    calc23Object(i, o23);

    return o17.getInt() + o23.getInt();
}

private void calc17Object(int i, IntWrapper o) {
    if (i % 17 == 0) 
        o.increment();
}
private void calc23Object(int i, IntWrapper o) {
    if (i % 23 == 0) 
        o.increment();
}


public static void main(String[] args) {
    TestSharedMembers t = new TestSharedMembers();
    final int NUM_ITERS = 20000000;

    double start = System.currentTimeMillis();
    int total = 0;
    for (int i=0; i&lt;NUM_ITERS; i++) {
        total += t.methodPrimitive(i);
    }
    double stop = System.currentTimeMillis();
    System.out.println(total);
    System.out.println(stop - start);

    start = System.currentTimeMillis();
    total = 0;
    for (int i=0; i&lt;NUM_ITERS; i++) {
        total += t.methodObject(i);
    }
    stop = System.currentTimeMillis();
    System.out.println(total);
    System.out.println(stop - start);

}
}
</code></pre>

<p>EDIT 2: Another example to test Jon's theory.</p>

<pre><code>public class TestSharedMembers {

protected int m17Multiples;
protected int m23Multiples;

public int methodPrimitive(int i) {

    m17Multiples = 0;
    m23Multiples = 0;

    calc17Primitive(i);
    calc23Primitive(i);

    return m17Multiples + m23Multiples;
}

private void calc17Primitive(int i) {
    if (i % 17 == 0) 
        m17Multiples++;
    if (i % 19 == 0) 
        m17Multiples++;
    if (i % 5 == 0) 
        m17Multiples++;
    if (i % 43 == 0) 
        m17Multiples++;
    if (i % 41 == 0) 
        m17Multiples++;
    if (i % 91 == 0) 
        m17Multiples++;
}
private void calc23Primitive(int i) {
    if (i % 23 == 0) 
        m23Multiples++;
    if (i % 17 == 0) 
        m23Multiples++;
    if (i % 19 == 0) 
        m23Multiples++;
    if (i % 5 == 0) 
        m23Multiples++;
    if (i % 43 == 0) 
        m23Multiples++;
    if (i % 41 == 0) 
        m23Multiples++;
    if (i % 91 == 0) 
        m23Multiples++;
}



/// using object wrappers
class IntWrapper {
    private int mInt1;
    private int mInt2;
    public IntWrapper(int i1, int i2) {
        mInt1 = i1;
        mInt2 = i2;
    }
    public int getInt1() {
        return mInt1;
    }
    public int getInt2() {
        return mInt2;
    }
    public void increment1() {
        mInt1++;
    }
    public void increment2() {
        mInt2++;
    }
}
public int methodObject(int i) {

    IntWrapper o = new IntWrapper(0,0);

    calc17Object(i, o);
    calc23Object(i, o);

    return o.getInt1() + o.getInt2();
}

private void calc17Object(int i, IntWrapper o) {
    if (i % 17 == 0) 
        o.increment1();
    if (i % 19 == 0) 
        o.increment1();
    if (i % 5 == 0) 
        o.increment1();
    if (i % 43 == 0) 
        o.increment1();
    if (i % 41 == 0) 
        o.increment1();
    if (i % 91 == 0) 
        o.increment1();
}
private void calc23Object(int i, IntWrapper o) {
    if (i % 23 == 0) 
        o.increment2();
    if (i % 17 == 0) 
        o.increment1();
    if (i % 19 == 0) 
        o.increment1();
    if (i % 5 == 0) 
        o.increment1();
    if (i % 43 == 0) 
        o.increment1();
    if (i % 41 == 0) 
        o.increment1();
    if (i % 91 == 0) 
        o.increment1();
}


public static void main(String[] args) {
    TestSharedMembers t = new TestSharedMembers();
    final int NUM_ITERS = 20000000;

    double start = System.currentTimeMillis();
    int total = 0;
    for (int i=0; i&lt;NUM_ITERS; i++) {
        total += t.methodPrimitive(i);
    }
    double stop = System.currentTimeMillis();
    System.out.println(total);
    System.out.println(stop - start);

    start = System.currentTimeMillis();
    total = 0;
    for (int i=0; i&lt;NUM_ITERS; i++) {
        total += t.methodObject(i);
    }
    stop = System.currentTimeMillis();
    System.out.println(total);
    System.out.println(stop - start);

}
}
</code></pre>
