[omniORB] omniorb and omniorbpy speed

Timothy Docker timd@macquarie.com.au
Tue, 28 Nov 2000 11:20:35 +1100 (EST)



Hi,

I'm (still) evaluating using omniorbpy in lieu of fnorb. As I has
hoped, omniorbpy is fast, but not as quick as I might have hoped. I 
have written a simple client that requests a large data structure from 
a remote service. I have written the client 3 times:

	- Orbacus 3.3.2 (the orb we use for C++ development), compiled
          with sun CC-4.2

	- omniORB 3.0.2 compiled with g++ 2.95

	- omniORBpy (on top of omniORB 3.0.2) as above.

(all under solaris). When run, I get the following execution times....

 | tcc2:any_test $ time ./obtest 
 | 4961 rows retrieved
 | 
 | real    0m2.688s
 | user    0m0.630s
 | sys     0m0.040s
 | tcc2:any_test $ time ./omnitest 
 | 4961 rows retrieved
 | 
 | real    0m4.276s
 | user    0m2.130s
 | sys     0m0.170s
 | tcc2:any_test $ time ./omnipy_test
 | 4883 rows retrieved
 | (with 12 cols)
 | 
 | real    0m11.878s
 | user    0m9.410s
 | sys     0m0.170s
 | tcc2:any_test $ 


These times are quite repeatable. Comparing the local (user) cpu
times, the omniorb C++ times are about 3 time slower than Orbacus,
and, more significantly the omniorb_py times are 4 times slower
again. Is omniorbpy slow when dealing with anys?

I don't have a good profiling tool that works with gcc, so I can't
easily work out where the time is being spent. Any suggestions on why
making the request via python is so much slower than C++? I assume
that the time is taken converting the 60,000 or Anys to their python
representaion. The any's contain only basic types (strings and
doubles). 

FYI attached is the (manually summarised) IDL, the C++ and python clients.

Any tips or pointer would be _much_ appreciated.

Tim

----------------------------------------------------------------------
module Common
{
    // Basic Sequence types
    typedef sequence<string> StringSeq;
    typedef sequence<long> LongSeq;
    typedef sequence<boolean> BooleanSeq;
    typedef sequence<any> AnySeq;
    typedef sequence<AnySeq> AnySeqSeq;
};

module Deals
{
    typedef Common::AnySeq     Label;
    typedef Common::AnySeqSeq  LabelSeq;
};

module RealTime
{
    typedef double TimeStamp;

    // Possible exceptions
    exception Error         { string reason; };

    /** RT breakdown report */
    interface Breakdown
    {
	readonly attribute Common::StringSeq categoryLabels;
	readonly attribute Common::StringSeq valueLabels;

	struct Results
	{
	    long sizeBeforeFilter;
	    long sizeAfterFilter;
	    TimeStamp lastUpdate;
	    Deals::LabelSeq categories;
	    Deals::LabelSeq values;
	    Deals::Label total;
	};
	    
	Results currentBreakdown(
	    in string filterExpression,

	    in Common::LongSeq showCategoryLabels,
	    in Common::BooleanSeq reverseCategories,

	    in Common::LongSeq showValueLabels
	    ) raises (Error);
    };
};

#endif

----------------------------------------------------------------------
#include "realtime.hh"
#include <fstream.h>
#include <stdlib.h>
#include <string.h>

Common::StringSeq_var categoryLabels;
Common::StringSeq_var valueLabels;

Common::LongSeq showCategoryLabels;
Common::BooleanSeq reverseCategories;
Common::LongSeq showValueLabels;

void
addLabel( const char *name )
{
    for( int i = 0; i < categoryLabels->length(); i++ )
    {
	if( !strcmp( name, categoryLabels.in()[i] ) )
	{
	    showCategoryLabels.length( showCategoryLabels.length()+1 );
	    showCategoryLabels[ showCategoryLabels.length()-1 ] = i;
	    reverseCategories.length( reverseCategories.length()+1 );
	    reverseCategories[ reverseCategories.length() - 1 ] = 0;
	    return;
	}
    }
    cerr << "No category called " << name << endl;
    exit(1);
}

main( int argc, char *argv[] )
{
    int i;

    CORBA::ORB_ptr orb = CORBA::ORB_init(argc, argv);
    const char* refFile = "breakdown.ref";
    ifstream in(refFile);
    char s[1000];
    in >> s;
    CORBA::Object_var obj = orb->string_to_object(s);
    RealTime::Breakdown_var b;
    b = RealTime::Breakdown::_narrow( obj );

    RealTime::Breakdown::Results_var results;

    categoryLabels = b->categoryLabels();
    valueLabels = b->valueLabels();
    
    showValueLabels.length( valueLabels->length() );
    for( i = 0; i < valueLabels->length(); i++ )
	showValueLabels[i] = i;

    addLabel( "zzzzz" );
    addLabel( "xxxxx" );

    results = b->currentBreakdown( "", showCategoryLabels, reverseCategories,
				   showValueLabels );
    cout << results->categories.length() << " rows retrieved" << endl;
}
----------------------------------------------------------------------
import sys
from omniORB import CORBA
from idl import RealTime


def main(argv):
    global orb, boa
    orb = CORBA.ORB_init(argv, CORBA.ORB_ID)
    b = orb.string_to_object( open( "breakdown.ref" ).read() )

    categoryLabels = b._get_categoryLabels();
    valueLabels = b._get_valueLabels()

    showCategoryLabels = []
    showCategoryLabels.append( categoryLabels.index( "zzzzz" ) )
    showCategoryLabels.append( categoryLabels.index( "xxxxx" ) )
    reverseCategories = [0] * len(showCategoryLabels)
    showValueLabels = range( len(valueLabels) )
    
    results = b.currentBreakdown( "", showCategoryLabels, reverseCategories,
                                  showValueLabels )
    print "%d rows retrieved" % len(results.categories)
    print "(with %d cols)" % (len(showCategoryLabels)+len(showValueLabels))
    
main(sys.argv)