perl XS + CORBA benchmark

Jan 25, 2007 21:25


всевозможный код

IDL интерфейс сервера:

#ifndef GF_LOGGING_SERVICE_IDL
#define GF_LOGGING_SERVICE_IDL

#include

#pragma prefix "goodoo.ru"

module GoodooFacilities
{
typedef CosNaming::Name Key;
typedef CosLifeCycle::Criteria Criteria;
typedef long TimeStamp;

enum EventSeverity
{
SEVERITY_SHOWSTOPPER,
SEVERITY_ERROR,
SEVERITY_WARNING,
SEVERITY_INFO,
SEVERITY_DEBUG,
SEVERITY_TRACE
};

interface Event
{
readonly attribute TimeStamp eventTime;
attribute EventSeverity severity;
readonly attribute string message;
void handle();
};

exception InvalidEventKey
{
Key eventKey;
};

interface EventLoggingService
{
oneway void logAnyEvent(in Key eventKey, in Criteria eventCriteria);
oneway void logEvent(in Event aEvent);
};

};

#endif

тестируемые функции:

на стороне CORBA-сервера (тупо срем в cerr):

void GoodooFacilities_EventLoggingService_i::logAnyEvent (
const ::GoodooFacilities::Key & eventKey,
const ::GoodooFacilities::Criteria & eventCriteria
)
ACE_THROW_SPEC ((
CORBA::SystemException
))
{
// Add your implementation here
// eventCriteria.

cerr << "Got event! :)" << endl;
long keysNo = eventKey.length();

cerr << "Key: " << endl;
for (int i = 0; i < keysNo; i++) {
cerr << "[" << i << "]: " << eventKey[i].id.in() << " = " << eventKey[i].kind.in() << endl;
}

keysNo = eventCriteria.length();

cerr << "Criteria:" << endl;

for (int i = 0; i < keysNo; i++) {
string criteriaName( eventCriteria[i].name );

cerr << "[" << i << "] " << criteriaName << " = " ;
const char* buff;
CORBA::Long longValue;
CORBA::Double doubleValue;
if ( eventCriteria[i].value >>= buff ) {
cerr << buff;
} else if ( eventCriteria[i].value >>= longValue ) {
cerr << longValue;
} else if ( eventCriteria[i].value >>= doubleValue ) {
cerr << doubleValue;
}

cerr << endl;

}
}

XS

bool logEvent(HV* key, HV* criteria)
{
try {
long keyNo = hv_iterinit(key);

GoodooFacilities::Key eventKey(keyNo);
eventKey.length(keyNo);

HE* hashEntry = hv_iternext( key );

for (int i = 0; i < keyNo; i++) {
long keyLength = 0;
string hashKey = hv_iterkey(hashEntry, &keyLength);
string hashValue;
SV* hashValueSV = hv_iterval(key, hashEntry);

if ( SvOK(hashValueSV) && SvPOK(hashValueSV) ) {
hashValue = SvPV(hashValueSV, PL_na);
} else {
cerr << "Event key hash entry [" << i << "] ({" << hashKey << "})has invalid value type" << endl;
}

// cerr << "Event key hash entry [" << i << "]: " << hashKey << " = " << hashValue << endl;

eventKey[i].id = CORBA::string_dup( hashKey.c_str() );
eventKey[i].kind = CORBA::string_dup( hashValue.c_str() );
hashEntry = hv_iternext( key );
}

keyNo = hv_iterinit(criteria);

GoodooFacilities::Criteria eventCriteria(keyNo);
eventCriteria.length(keyNo);

hashEntry = hv_iternext( criteria );

for ( int i = 0; i < keyNo; i++ ) {
long keyLength = 0;
string hashKey = hv_iterkey(hashEntry, &keyLength);

eventCriteria[i].name = CORBA::string_dup( hashKey.c_str() );

SV* hashValueSV = hv_iterval(key, hashEntry);

if ( SvOK(hashValueSV) ) {
if ( SvPOK(hashValueSV) ) {
// cerr << "Criteria key [" << i << "] ('" << hashKey << "') is a string" << endl;
eventCriteria[i].value <<= CORBA::string_dup( SvPV(hashValueSV, PL_na) );
} else if ( SvIOK(hashValueSV) ) {
// cerr << "Criteria key [" << i << "] ('" << hashKey << "') is an integer" << endl;
long value = SvIV(hashValueSV);
eventCriteria[i].value <<= static_cast(value);
} else if ( SvNOK(hashValueSV) ) {
// cerr << "Criteria key [" << i << "] ('" << hashKey << "') is a double" << endl;
double value = SvNV(hashValueSV);
eventCriteria[i].value <<= static_cast(value);
}
}
//eventCriteria[i].value <<= CORBA::string_dup("авотхуй");
hashEntry = hv_iternext( criteria );
}

logging_service->logAnyEvent(eventKey, eventCriteria);
}
catch( CORBA::Exception &ex ) {
cerr << "CORBA exception caught!" << endl;
return false;
}
return true;
}

Код бенчмарка:

use Benchmark qw(:all :hireswallclock);
use GoodooFacilities::LoggingService;

my $ior = 'corbaloc::localhost:12345/LoggingService';

GoodooFacilities::LoggingService::initialize($ior)

my $count = 100000;

diag("starting benchmark");
my $t = timeit( $count, sub { logEvent( { Event => 'Message', Namespace => 'Metro2033' },
{ message => 'blablabla', severity => 0, PI => 3.14 } ) } );

diag("benchmark finished");
diag( "$count loops of event sending took: ". timestr($t));

GoodooFacilities::LoggingService::cleanup();

Условия

вызовы локальные, через stub/skeleton, без DII. завтра протестирую по сети.
OS - Debian 2.6.18-3-686
ORB - ACE+TAO 5.4.7-12
perl 5.8.8
Сервер - однопоточный в консоли. Клиент тоже :)
Результаты 5 прогонов бенчмарка

# 100000 loops of event sending took: 34.5186 wallclock secs ( 4.58 usr + 0.30 sys = 4.88 CPU) @ 20491.80/s (n=100000)
# 100000 loops of event sending took: 99.3214 wallclock secs ( 5.10 usr + 0.24 sys = 5.34 CPU) @ 18726.59/s (n=100000)
# 100000 loops of event sending took: 37.9359 wallclock secs ( 4.76 usr + 0.23 sys = 4.99 CPU) @ 20040.08/s (n=100000)
# 100000 loops of event sending took: 36.3202 wallclock secs ( 4.67 usr + 0.21 sys = 4.88 CPU) @ 20491.80/s (n=100000)
# 100000 loops of event sending took: 34.793 wallclock secs ( 4.71 usr + 0.25 sys = 4.96 CPU) @ 20161.29/s (n=100000)

Итого среднее число сообщений, отправляемых в секунду, из 5-ти прогонов составляет 20161.29.

я доволен :)

perl, corba, есть контакт!, xs, программизм, работа, щастье, c++

Previous post Next post
Up