Walkaround suggestion to structs

Princenc suggested:
“I just want fast memory mapped interfaces between ByteBuffers and Java Objects.”

I wander if the brilliant engineers at Sun could implement this in their hotspot compiler? ->

While I don’t really understand what Princec is talking about I do understand that there are people making small time classes for specific ops or whatnot which structs are generally used for under C and C#.

I have a better idea than to include structs.

Have the hotspot compiler measure the cost of the inside of the class (variable sizes and whatnot) and if the class size is below a certain threshold the hotspot compiler can perform a very aggressive operation on it to significantly reduce overhead of that class.

Why hasn’t anyone suggested this before?

Can someone suggest this on JSR assuming they agree with the intention rather than my implementation.

In a nutshell, no, it can’t be done like that. There’s only one solution to the problem, and there are only two arguments going on about it:

  1. “I don’t want no steeking structs in my beautiful language.” A very lame counterargument from the same well-meaning people who should have devoted their efforts to getting the generics implementation fixed instead of bashing structs.

  2. “I don’t want it implemented like that, I want it like this…” etc. Quibbles over details.

Cas :slight_smile:

BTW, my solution wasn’t refering to your problem.

I was using you as an example and didn’t explain why I used you in my details.

My solution doesn’t fix your problem of wanting to pass objects as memory streams.

I merely asking if my solution repairs the issue of small classes being agressively optimised so there is very little overhead in using them.

There is no way to realistically shrink small classes any smaller than big classes. The overhead of an instance is constant. The only thing that can be done is local data can be allocated on the stack but we’ve been waiting an awfully long time for this much-requested feature.

Cas :slight_smile:

Of course Hotspot can optimize some classes as value types (or structs), but it’s not as easy as you make it sound. What happens for example if there are multiple references to the same value object? Escape analysis and other methods can solve many of these problems and optimize objects as value types, but in the current JRE this is not fully exploited. For example, an immutable vector class is slower than a mutable with the current JRE. It shouldn’t have to be.

Btw, I’m against adding a “struct”-type element to the Java language as it would introduce lots of problems for little value.

All I want is syntactic sugar around a VM enhancement. The struct keyword could be used or it could simply detect classes extending javax.nio.Struct. It doesn’t matter. All these wranglings fall into objection category #2. There is otherwise no valid reason to be against the purpose of “structs” or “memory mapped object instances”.

Cas :slight_smile:

class someClass implements unmutable (or fixedSize)
would be better. Do you remmember what happened to Vector? Some peole use it because simillar class is in C++.

Actually can you describe how would memory implementation differ in both cases?

You need a refference for both an object and a struct. You migth save some space by serialization of Object array into a single array. It could save some refferences, but could cause different problems.
Or were you interested in a bit copy of an object and throwing it somewhere else?

You seems to believe in a incredible speed of a stack. It’s not the case in actual programming. Direct memory call is faster than push, or pop the stack. Of course direct memory call could be 250 CPU cycles, so difference between talking to memory and stack out of L2 cache is very small.

Er, who are you asking?

Cas :slight_smile:

You can answer if you want.

The “struct” proposal is all about a) maintaining 100% java language compatibility without introducing any wierdness, b) completely removing the object overhead for large collections of mapped objects, and c) putting a nice object oriented front end on top of a flat buffer of memory.

A single instance of a struct has a bytebuffer on which it lives, and a position. A struct is a proper first class object like any other java object; it’s passed by reference, it’s garbage collected, etc. The only difference is that a struct’s primitive fields are not allocated in the heap; instead they are mapped directly into the bytebuffer at the specified position in a consistent well-defined manner. Object fields are ignored for the purposes of the mapping.

What this means is you can have a huge big bytebuffer with a memory-friendly representation of, say, a BSP tree, just like in C or any other sane language. You create an instance of a Node struct, attach it to the bytebuffer, and position it somewhere. Bingo! The Node instance is effectively a pointer to a struct, except it’s totally safe. You can do what the hell you like with your struct instance, it’s just another Object.

So that’s what structs do.

As for escape analysis - EA is just a really cheap optimisation for a compiler to do. It really is pretty simple to implement. It won’t actually bring any speed increases in memory access or reduce object overhead particularly. What it will do is almost completely eliminate tons of little bits of garbage cluttering up the GC, leaving it to do its work on more important stuff. As a side effect it also means you can guarantee allocation time in many situations which is very important for a lot of people. Excelsior have used EA to very great effect in their JET JVM.

Cas :slight_smile:

[quote]The “struct” proposal is all about a) maintaining 100% java language compatibility without introducing any wierdness, b) completely removing the object overhead for large collections of mapped objects, and c) putting a nice object oriented front end on top of a flat buffer of memory.
[/quote]
Just out of interest…c.f. the thread on “java vs C++”…would structs as you want them help the issue of fast load times on weak CPU’s, where in C++ you bake-in the pointers to the serialized file?

e.g. a low-power CPU (could be console, could be mobile) streams in a bytebuffer with all the level-data, and uses structs to start accessing the high-level object structure without actually having to go through the time of parsing game-file etc.

And, indeed, possibility of partial loading? Start using the structs before the full BB has finished streaming in? (although on low-power devices, usually you’d have to memmap or similar instead because you don’t tend to have much RAM)

All pointers of course are meaningful only in the context of the buffer, i.e. there are no pointers, only “byte offsets” which you could move your struct to.

You could memmep a file into a mapped bytebuffer and use structs on it - nice. That’s just one of the many great conveniences this API would bring.

Cas :slight_smile:

Can you explain more how the syntax for this would look? Do you just create a normal Java class and map it into a byte buffer, or something else?

I guess you could define a struct like this:


class MyStruct {
  public int x;
  public int y;
  public char[] chars = new char[5]; // ?????
}

Object references are ignored you say. Are boolean’s also ignored?

How do you map instances of this struct into a byte buffer? Something like this (?):


MyStruct instance = MagicByteBufferAllocator.allocate(MyStruct.class, byteBuffer, index);

???

Ideally:


public struct Vector3f {
private float x, y, z;
}

but failing that


public class Vector3f extends javax.nio.Struct {
private float x, y, z;
Vector3f(ByteBuffer buffer) {
super(buffer);
}
}

Cas :slight_smile:

Ok, what about arrays?


struct Data {
  char[5] chars; // ?
}

And you must be able to put a struct in a struct, right?


struct Data1 {
  int x;
  int y;
}

struct Data2 {
  Data1 d;
}

Data2 d2 = new Data2();

Would that mean that the value of ‘d2.d’ is also an object that is allocated when d2 is allocated?

Will you guys scrap the ‘struct’ keyword.

All I’m asking for are compile time optimisations on small objects(classes) that can make them use less memory and have faster access than a normal class.

Yeah, just forget the word “struct”. They’re objects like any other objects, and all they are is a little sliding view on top of a bytebuffer.

Object references are ignored in these mapped objects as there is no meaningful mapping of Object types to bytes - even for arrays. Think about it. So array types, sub-Structs, etc. - none of these will work, they’ll be null (unless you go explicitly setting them to something). So just forget about using Structs or mapped objects in this way. They’re for large quantities of complex primitive data, such as can be found in I/O and 3D.

Cas :slight_smile:

So if I understand correctly, the difference between using objects for value collections and using a struct is how they are stored in the “stack” / extra calls?

Does using objects to store values give that more overhead than using structs, even on today’s fast systems? :-/

Vastly more overhead. Not only does it hugely tax the garbage collector but can almost double your memory requirements. Try storing a decent OOP version of a BSP in memory. Try loading one up quickly for that matter!

Cas :slight_smile:

[quote]almost double your memory requirements.
[/quote]
Make your leaf nodes a bit bigger (i.e. put several polygons in each leaf node). I’m storing millions of curved lines (roads) with a 2-d index structure. The index is small relative to the actual data.