Java Generics "Compiler"

Hi Folks, my first post here, so greetings and thanks for all the great topics I already looked at ;D
I’m searching quite a while now for something that I would call a generics compiler.
The Problem: I wrote a NavMesh class that calculates an approximation to the minimal convex polygons between obstacle polygons. It’s working quite fine, but sometimes I get floating-point related errors that lead to completely wrong meshes. To solve this I could use additional math to prevent this, but according to the site I found the formulas on it will add about 30% overhead and since I will need to update the mesh in-game I’m considering to change to integer arithmetic completely.
Now due to the IMO poor implementation of Java generics, I didn’t use them to abstract the base datatype because that would lead to a lot of autoboxing and unnecessary references. So what I imagine is something like this:
You have a class Vector in Vector.java. Now I want some tool that can produce a VectorI / VectorF class that would create the same class, with the same methods and so on just replace the BaseType by int/float (not Integer/Float). Another approach would be some sort of bytecode manipulation tool, that is able to completely replace all Vector with VectorF, but I think I would prefer the first approach since I would be able to do something like “manual partial specialization”.
Anyway, as I said I couldn’t find something like that.

Thanks for any advice!
Greetings,
Mene

PS: As you might have guessed I used to do most stuff with C++, so if my idea is just not a good “java-aproach”, please let me know ;D

Just write the class using int. If you want to specialise it with different primitive, you’re just going to have to bite the bullet and do it manually.

BTW there exist a bunch of pre-built primitive specialisations for the entire collections framework somewhere - we were just talking about it in another thread about map performance… you might want to use some of them.

Cas :slight_smile:

Java interns Integer objects from -127 to 127, and has plenty of other optimizations for auto-boxing. In the grand scheme of things it’s rarely a performance hit.

IMHO just write it and optimize your code later when it’s done.

Thanks a lot so far!

I read something different, I think in “effective java”, but I’ll give it a try and if it doesn’t work… well find and replace will probably ;D

BTW didn’t know the “Java interns Integer objects from -127 to 127”… but if I understood it right it just means, that all Integer instances with a value of e.g. 110 are the same reference (and that is true for any other number in this range)

Anyways, as said I’ll give it a try!

+1, be sure not to optimize prematurely. It may seem horrible that autoboxing is happening, but often it doesn’t actually matter.

First, you probably want to use ArrayList and not Vector. Vector is synchronized, ArrayList is not.

You could write your own array backed list class. It is probably the easiest collection to implement. You don’t have to implement the List interface, just provide the methods you actually need.

The fastutil project does as you ask, it uses code generation to make just about every primitive type combination for maps, lists, sets, etc (eg, look at IntList):
http://fastutil.dsi.unimi.it/
The resulting JAR is ~13mb, so I recommend using ProGuard to rip out all the classes you don’t want to use:


There are other, smaller projects that have primitive collections (eg, look at IntArrayList):
http://acs.lbl.gov/~hoschek/colt/
http://trove4j.sourceforge.net/

Thanks, that looks interesting, especially the tool idea sound what I want.
But I think I didn’t express me clearly enough, when I spoke about Vector I meant the mathematical Vectors that have dot product and so on. E.g. I’d like to replace Java3d’s Vector3f with an Vector3 and get the exact same results (on a bytecode level) but it’ll be more flexible, because I could use it in this manner:


class NavMesh<REAL extends Number> {
    Vector3<REAL> someInternalValue;

    public void addPoint(Vector3<REAL> point);
}

And then some tool would process the whole source code and give me:


class NavMeshf {
    Vector3f someInternalValue;

    public void addPoint(Vector3f point);
}

class NavMeshd {
    Vector3d someInternalValue;

    public void addPoint(Vector3d point);
}

class NavMeshi {
    Vector3i someInternalValue;

    public void addPoint(Vector3i point);
}

And replace all occurrences of NavMesh with NavMeshf and so on…

You can do something like this with a bytecode generator, but I have a feeling you’re thinking a bit C++ centric here and making an unnecessarily complex task out of it to try and do something in Java which it isn’t massively well suited for. IMHO you should probably write whatever library you want to with one kind of primitive type throughout and get all that working, and then maybe worry about other types. The case for Vector and Vector is exactly the sort of thing that unfortunately doesn’t map from C++ to Java well at all. Just one of those shortcomings you have to code your way around.

Cas :slight_smile:

your computation/method content will also be very different in some case int vs flot , so you cant use the same code for both (int will need to be scaled befre dividing when float doen’t)

Ok, I just wanted to do some micro-benchmarking to see what the compiler/run time optimizer might be able to archive.
Again I’m quite disappointed. A friend told me I would be able to use the normal operators (+, -, *, /) if my generic parameter was constrained to Number, but this is not the case. So for serious calculations the code would become totally unreadable.
When I first did some java stuff I was quite euphoric about the ease of the language, but these are serious limitations: You’re either unmaintainable and probably slow or inflexible.
For now I will stick to

Thanks again!

Agreed, Java’s generics with numbers can be a bit misleading. For example you can’t cast a Float to an int, you have to turn it into a float first.

You could build some sort of pre-processor which will just generate the class for you. The idea is that when you use Vector it will copy the original generic vector class and then replace all of it’s generic parameters with float. With this Vector, Vector and Vector will all generate three seperate classes.

Yes, this was my first idea, too. Partial specialization could be archived via annotations or maybe even by using concrete types like:


class Triangle2<Real extends Number> {
  public boolean isInCircumCircle(Vector2<Float>) {
    // Numerical stability aware calculation
  }

  public boolean isInCircumCircle(Vector2<Integer>) {
    // Simple calculation
  }

}

I also considered using bytecode manipulation tools, but that would be almost impossible due to type erasure.
If using this approach there still is the problem that you can’t use the normal operators. Thus I might end up using a generator which would know that Triangle2f is supposed to be Triangle2 and would generate Triangle2i. The problem here: Triangle2f will contain isInCircumCircle(Vector2f) and isInCircumCircle(Vector2i), thus I need to create Vector2i first… anyway, i guess i’ll finish the float implementation first and maybe I’m even better off using some simple regex and copy/replace.
If I write a tool I’ll let you know, just wanted to know if someone had done some stuff like this before.

I believe Cup (which is a compiler compiler for generating grammers) has full java syntax as one of it’s examples. You could take this and then alter it to your needs.