Home
 

Compound Data Types

Compound Data Types

In this section we will take a closer look at the compound data types array and structure. Note that from this point forward we will only deal with synchronous calls.

Array

Method

Arrays will only be tested with ints. As for the simple data types, we simply call a method 1000 times, with an increasing number of array elements. Note that again, we transfer the same amount of data forth and back.

        ...
        else if (method.equals("sync_aLaL1")) {
            int[] din = new int[1];
            Perf.RTTArraysPackage.longArray1Holder dout = 
                new Perf.RTTArraysPackage.longArray1Holder();
            t1 = System.currentTimeMillis();

            for (int i=0; i<1000; i++)
                rtt.sync_aLaL1(din, dout);

            t2 = System.currentTimeMillis();
        }
        else if (method.equals("async_aL1")) {
            int[] din = new int[1];

            t1 = System.currentTimeMillis();

            for (int i=0; i<1000; i++)
                rtt.async_aL1(din);

            t2 = System.currentTimeMillis();
        }
        ...

Figure 4-4. RTT Calls for Arrays

Results

Arrays contain just the plain blocks attached to each other, as specified by the GIOP (General Inter-ORB Protocol, [5]). Thus, Figure 4-5 shows exactly what was expected: A linear correlation between the number of elements and the round trip time.

Figure 4-5. Size of Arrays

Structure

Method

The calls look as before. We only put ints into the structure.

        ...
        else if (method.equals("sync_sLsL1")) {
            Perf.RTTStructsPackage.longStruct1 din =
                new Perf.RTTStructsPackage.longStruct1();
            Perf.RTTStructsPackage.longStruct1Holder dout = 
                new Perf.RTTStructsPackage.longStruct1Holder();
            t1 = System.currentTimeMillis();

            for (int i=0; i<1000; i++)
                rtt.sync_sLsL1(din, dout);

            t2 = System.currentTimeMillis();
        }
        ...

Figure 4-6. RTT Calls for Structures

Results

My intuition suggested that structures are encoded similar to arrays, simply each member after the other. Taking a look at Figure 4-7 is therefore a little surprising. At 100 elements we see a large stray between arrays and structures.

Figure 4-7. Array-Struct Comparison

First, a look at the standard might provide some clue. It says the following.

The components of a structure are encoded in the order of their declaration in the structure. Each component is encoded as defined for its data type.

It seems we have to dig a little bit deeper, into the source code, to find out what is going on. The following code is taken from a Helper class for structures, generated by the IDL compiler.

final public class longStruct10Helper
{
    ...
    private static org.omg.CORBA.TypeCode typeCode_;

    public static org.omg.CORBA.TypeCode
    type()
    {
        if(typeCode_ == null)
        {
            org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init();
            org.omg.CORBA.StructMember[] members = 
              new org.omg.CORBA.StructMember[10];

            members[0] = new org.omg.CORBA.StructMember();
            members[0].name = "d0";
            members[0].type =
              orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_long);

            members[1] = new org.omg.CORBA.StructMember();
            members[1].name = "d1";
            members[1].type =
              orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_long);

            ...

            typeCode_ = orb.create_struct_tc(id(), "longStruct10", 
                                             members);
        }

        return typeCode_;
    }
    ...
}

And below the counterpart for arrays.

final public class longArray10Helper
{
    ...
    private static org.omg.CORBA.TypeCode typeCode_;

    public static org.omg.CORBA.TypeCode
    type()
    {
        if(typeCode_ == null)
        {
            org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init();
            typeCode_ = orb.create_alias_tc(id(), "longArray10", orb.create_arr\
ay_tc(10, orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_long)));
        }

        return typeCode_;
    }
    ...
}

This type code creation introduces some overhead, but the result is cached in a static variable, which means that it is necessary only once.

Just as the difference between ints and floats, this effect remains unexplained. However, we can speculate about the cause. Below you see the read() methods in the Helper classes for structures and arrays, respectively. Structures are read element by element, whereas arrays are read as a whole. This might be the cause for the difference, but is not verified.

    public static longStruct10
    read(org.omg.CORBA.portable.InputStream in)
    {
        longStruct10 val = new longStruct10();
        val.d0 = in.read_long();
        val.d1 = in.read_long();
        val.d2 = in.read_long();
        val.d3 = in.read_long();
        val.d4 = in.read_long();
        val.d5 = in.read_long();
        val.d6 = in.read_long();
        val.d7 = in.read_long();
        val.d8 = in.read_long();
        val.d9 = in.read_long();
        return val;
    }
    public static int[]
    read(org.omg.CORBA.portable.InputStream in)
    {
        int[] val;
        int len0 = 10;
        val = new int[len0];
        in.read_long_array(val, 0, len0);
        return val;
    }

However, this has very little effect on structures with few, say 10, members. As structure with many members, say 100, performs quite poorly, but a structure with that many members is not likely to occur at all.