简体   繁体   中英

Lookup table in Java

When I want to speedup part of codes, I use a lookup table instead of a function. In other languages I use global arrays to do this job. I pre-calculated all return values and put them in an array.

Here is an example of a function :

public static int Box(int c) { /* c value range is 0-80 */
    return ((c / 9) / 3) * 3 + ((c % 9) / 3);
}

I could instead use an array like this :

int Box[] = {0,0,0,1,1,1,2,2,2,0,0,0,1,1,1,2,2,2,0,0,0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,3,3,3,4,4,4,5,5,5,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,8,8,8,6,6,6,7,7,7,8,8,8,6,6,6,7,7,7,8,8,8}

Java doesn't have global arrays!

What would be the best way way to do this so I can access these values?

In Java, the equivalent of globals are public static variables. If you want to make the static variable immutable, then it should also be declared as final.

Also, the naming convention in Java for static variables is to capitalize the entire name, and separate words with underscores (ex: SOME_BOX).

Using your example above, you can do:

public static final int[] BOX = {0,0,0....};

You can still use global variables. You just need to put them in a class.

public class PrecalculatedValues{
    public static final int BOX[]={0,0,0,1,1,1,...};
}

You can access BOX later in your code like so:

public static void main(String[] args) {
    System.out.println(PrecalculatedValues.BOX[0]);
}

Though it is possible to use a lookup table it is completly unnecessary in this case, since the equation can be calculated without branches in a couple of cycles.

When using arrays as a lookup table branches will become necessary because of the ArrayIndexOutOfBounds checks.

I would recommend to put a static array inside a class where that method is located and still call the method from outside code and just use the array from within the function. Yes, you will have some overhead for a funcall but I suppose you're not trying to gain like 0.001% of performance? Also JIT will probably simplify it. Most importantly your interface will be consistent and it will look like a normal function not like some hack. If you're trying to get some performance from a costly function by precalculation you can also consider memoization. The thing with hiding this array behind the funcall is that you can use any technique of caching or precalculation later without disturbing public interface.

Eg

class A {
    private final static int values[] = {0, 1, 2 ... };

    public int myFun(int x){
        return values[x];
    }
}

for one you could just simplify your function (the /9/3*3 and the parens are very unnecessary. I know this is an example but just always look for ways of simplifying)

secondly if you function is simple enough, the "spedup" methods are not necessarily faster. Generally your lookup table method is not exactly scalable

third if you still want a lookup table method, just create an object that holds the values.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM