Home
 

Number of Methods

Number of Methods

Now we will take a closer look at the influence of the number of methods in an object.

Method

Here we have quite a number of methods to call. Instead of hardcoding them we use the Java Reflection API to create references to the methods and then call them.

        ...
        long t1 = 0;
        long t2 = 0;
        if (method.equals("sync_VV_1")) {
            RTTMethods1 methods = factory.createM1();
            int num = 1;
            java.lang.reflect.Method[] m = 
                        new java.lang.reflect.Method[num];
            
            for (int j=0; j<num; j++) {
                try {
                    m[j] = 
                        methods.getClass().getDeclaredMethod("sync_VV_"+j, null);
                }
                catch(Exception e) {
                    System.out.println("Error while invoking: "+e);
                }
            }

            try {
                t1 = System.currentTimeMillis();
                for (int i=0; i<loops; i++) {
                    for (int j=0; j<num; j++) {
                        m[j].invoke(methods, null);
                    }
                }
                t2 = System.currentTimeMillis();
                
            }
            catch(Exception e) {
                System.out.println("Error while invoking: "+e);
            }
        }
        ...
        System.out.println(t2-t1);

Figure 4-8. MethodClient.java

Results

The number of methods in an object should have very little influence. But let's take a look at the actual data first.

Figure 4-9. Number of Methods RTT

As can be seen above, the round trip time increases about 7% for 100 methods, and about 15% for 500 methods. Why does this happen?

Let's take a look at the GIOP (General Inter-ORB Protocol, [5]) again.

module GIOP { // IDL extended for version 1.1 and 1.2
    struct RequestHeader_1_2 {
        unsigned long request_id;
        octet response_flags;
        octet reserved[3];
        TargetAddress target;
        string operation;
        IOP::ServiceContextList service_context;
        // Principal not in GIOP 1.2
    };
};

Not surprisingly, the operation is encoded as a string. This string is then looked up in a table, via binary search, and the index is used for a switch, in which each case invokes the correct method. The actual code for an interface with one method is shown below.

    final public void
    invoke(org.omg.CORBA.ServerRequest _ob_req)
    {
        String _ob_op = _ob_req.op_name();
        final String[] _ob_names =
        {
            "sync_VV_0"
        };

        int _ob_left = 0;
        int _ob_right = _ob_names.length;
        int _ob_index = -1;

        while(_ob_left < _ob_right)
        {
            int _ob_m = (_ob_left + _ob_right) / 2;
            int _ob_res = _ob_names[_ob_m].compareTo(_ob_op);
            if(_ob_res == 0)
            {
                _ob_index = _ob_m;
                break;
            }
            else if(_ob_res > 0)
                _ob_right = _ob_m;
            else
                _ob_left = _ob_m + 1;
        }

        switch(_ob_index)
        {
        case 0: // sync_VV_0
            _OB_op_sync_VV_0(_ob_req);
            return;
        }

        throw new org.omg.CORBA.BAD_OPERATION();
    }

The above code segment (binary search with 1 element) takes about 55us to execute. The 500 methods equivalent (binary search with 500 elements) about 750us. A single method call takes 4.9ms on average for an object with 1 method (see Figure 4-9). With these numbers we can now try to predict the time to call an object with 500 methods. We take the single method call time, substract the lookup time for the method and add the lookup time for 500 methods, i.e. 4.9ms - 50us + 750us = 5.6ms. The actual measured value was 5.6ms, as can be seen in Figure 4-9.

In conclusion, the additional time needed seems to come from the binary search of the called methods in the array of all possible methods. Unless other system limitations kick in, the required time will continue to grow with O(ld n) of the binary search.

As discussed for structures before, an object with 500+ methods is not likely to occur and therefore should be a small issue in real life.