0

This is basically the same question as Implementing a C style bitfield in Java. But is there a way of doing this in a typed fashion without resorting to using a class? As an example, here is some 'C' code:

typedef struct
{
    unsigned int x: 8;
    unsigned int y: 8;
} point;

point getPoint()
{
    point p;
    p.x = 1;
    p.y = 2;
    return p;
}

"point" is nicely typed and the compiler passes it around as an int primitive type, which is very efficient. In java, one might use a class to contain the point and then write:

point getPoint()
{
    return new point(1,2);
}

I am trying to improve a heavily recursive java game program that uses a class "point" (among other simple classes) and so the jvm is doing zillions of new operations and taking an enormous amount of time in garbage collection. Changing the class "point" into a packed int may or may not help, but its worth a shot. But I would like to have a nice type "point" to use in the program rather than just declaring "int" everywhere I use the point.

Community
  • 1
  • 1

3 Answers3

0

If you ask the same question, you're bound to get the same answer. No.

There is no way to do this is Java, except doing it manually. You could define a long value and shift/mask two ints in there. Or you could have an int and store two shorts in there. But setting/getting the values you will need to do some shifting and masking.

See this question/answer: Packing two shorts into one int, dealing with negative and positive

Community
  • 1
  • 1
Roy van Rijn
  • 840
  • 7
  • 17
0

In Java it is not usually the size of the object that clobbers you - it is more usually how long you keep hold of it. However - in some cases what you may be looking for is a mutable int.

/**
 * Mutable integer.
 */
public class Mint {
  private int i = 0;

  public Mint () {
  }

  public Mint (int i) {
    this.i = i;
  }

  /**
   * @return the i
   */
  public int get() {
    return i;
  }

  /**
   * @param i the i to set
   */
  public int set(int i) {
    this.i = i;
    return i;
  }

  public int add ( int i ) {
    this.i += i;
    return i;
  }

  public int sub ( int i ) {
    this.i -= i;
    return i;
  }

  public int mul ( int i ) {
    this.i *= i;
    return i;
  }

  public int div ( int i ) {
    this.i /= i;
    return i;
  }

  public int mod ( int i ) {
    this.i %= i;
    return i;
  }

  @Override
  public String toString () {
    return Integer.toString(i);
  }
}

Please be very careful about using mutables - there is a very good reason why making classes immutable is a good idea.

Added

On further reading of your question this may not be as effective for you as it is your Point objects that are clogging your system. Perhaps you should make your Point objects mutable instead.

OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213
  • GC was slow. Then I retained the transposition table between moves rather than cleared before each move because often some of this data could be reused. Now all of the move objects live on until the first collision, which could be awhile, perhaps minutes. That made it really slow. – user3332817 Dec 08 '14 at 21:18
  • Sounds like you want mutable `Move` objects that accumulate. – OldCurmudgeon Dec 08 '14 at 22:42
0

jvm is doing zillions of new operations and taking an enormous amount of time in garbage collection.

How many distinct points are there? Perhaps it's worth making a cache of points and reusing them so you only create the few points you need and don't garbage collect at all.

Point should be a value object so as long as the x and y coords are the same it shouldn't matter which instance of Point is returned.

dkatzel
  • 31,188
  • 3
  • 63
  • 67
  • I used the x-y point as an example but actually I already converted that to a single int. The game board is 10x10, so only 100 points were needed. But there are two other heavily used classes: Move and ValueMove. Move(x,y) has 100*100 possible values, which also would fit into an int. So using a cache I could retain Move as a class by using a 10000 element array and have getMove(x,y) index the array and return the Move. ValueMove is a Move and a int value. This could be contained in a long using packing operations. ValueMove is a little too big for the cache idea. – user3332817 Dec 08 '14 at 20:34
  • A cache doesn't have to provide *All* possible values. Just the most used. – dkatzel Dec 08 '14 at 21:16