bump product version to 4.1.6.2
[LibreOffice.git] / testtools / source / performance / ubtest.cxx
blob9c1413f5bdb9cae7293590465f08b5203071d6ec
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <stdio.h>
22 #include <math.h>
23 #include <string>
24 #include <boost/unordered_map.hpp>
25 #include <map>
27 #include <osl/diagnose.h>
28 #include <osl/mutex.hxx>
29 #include <osl/module.h>
30 #include <osl/process.h>
31 #include <osl/thread.h>
32 #include <osl/conditn.hxx>
33 #include <osl/time.h>
35 #ifdef SAL_W32
36 #include <windows.h>
37 #else
38 #include <sys/times.h>
39 #include <unistd.h>
40 #endif
42 #include <rtl/string.hxx>
43 #include <rtl/strbuf.hxx>
44 #include <rtl/ustrbuf.hxx>
46 #include <uno/environment.hxx>
47 #include <uno/mapping.hxx>
49 #include <cppuhelper/factory.hxx>
50 #include <cppuhelper/implbase2.hxx>
52 #include <com/sun/star/lang/XServiceInfo.hpp>
53 #include <com/sun/star/lang/XComponent.hpp>
54 #include <com/sun/star/lang/XMain.hpp>
55 #include <com/sun/star/lang/XInitialization.hpp>
56 #include <com/sun/star/loader/XImplementationLoader.hpp>
57 #include <com/sun/star/registry/XRegistryKey.hpp>
58 #include <com/sun/star/bridge/XUnoUrlResolver.hpp>
59 #include <com/sun/star/container/XSet.hpp>
60 #include <com/sun/star/test/performance/XPerformanceTest.hpp>
62 #define NLOOP 200000000
64 using namespace osl;
65 using namespace cppu;
66 using namespace com::sun::star::uno;
67 using namespace com::sun::star::lang;
68 using namespace com::sun::star::loader;
69 using namespace com::sun::star::registry;
70 using namespace com::sun::star::bridge;
71 using namespace com::sun::star::container;
72 using namespace com::sun::star::test::performance;
75 #define SERVICENAME "com.sun.star.test.performance.PerformanceTest"
76 #define IMPLNAME "com.sun.star.comp.performance.PerformanceTest"
78 namespace benchmark_test
81 static inline sal_uInt32 getSystemTicks()
83 #ifdef SAL_W32
84 return (sal_uInt32)GetTickCount();
85 #else // only UNX supported for now
86 static sal_uInt32 nImplTicksPerSecond = 0;
87 static double dImplTicksPerSecond;
88 static double dImplTicksULONGMAX;
90 struct tms aTms;
91 sal_uInt32 nTicks = (sal_uInt32)times( &aTms );
93 if ( !nImplTicksPerSecond )
95 nImplTicksPerSecond = sysconf(_SC_CLK_TCK);
96 dImplTicksPerSecond = nImplTicksPerSecond;
97 dImplTicksULONGMAX = (double)(sal_uInt32)ULONG_MAX;
100 double fTicks = nTicks;
101 fTicks *= 1000;
102 fTicks /= dImplTicksPerSecond;
103 fTicks = fmod (fTicks, dImplTicksULONGMAX);
105 return (sal_uInt32)fTicks;
106 #endif
109 //--------------------------------------------------------------------------------------------------
110 static void out( const sal_Char * pText, FILE * stream = stderr,
111 sal_Int32 nStart = -1, sal_Char cFillchar = ' ' )
113 static sal_Int32 s_nPos = 0;
115 sal_Char ar[2] = { cFillchar, 0 };
116 while (s_nPos < nStart)
118 ::fprintf( stream, ar );
119 ++s_nPos;
122 ::fprintf( stream, pText );
124 for ( const sal_Char * p = pText; *p; ++p )
126 if (*p == '\n')
127 s_nPos = 0;
128 else
129 ++s_nPos;
132 //--------------------------------------------------------------------------------------------------
133 static inline void out( const OUString & rText, FILE * stream = stderr,
134 sal_Int32 nStart = -1, sal_Char cFillchar = ' ' )
136 OString aText( OUStringToOString( rText, RTL_TEXTENCODING_ASCII_US ) );
137 out( aText.getStr(), stream, nStart, cFillchar );
139 //--------------------------------------------------------------------------------------------------
140 static inline void out( double fVal, FILE * stream = stderr,
141 sal_Int32 nStart = -1, sal_Char cFillchar = ' ' )
143 sal_Char ar[128];
144 ::snprintf( ar, sizeof(ar), (fVal < 0.000001 ? "%g" : "%f"), fVal );
145 out( ar, stream, nStart, cFillchar );
147 //--------------------------------------------------------------------------------------------------
148 static inline void out( sal_Int64 nVal, FILE * stream = stderr,
149 sal_Int32 nStart = -1, sal_Char cFillchar = ' ' )
151 sal_Char ar[128];
152 ::snprintf( ar, sizeof(ar), "%ld", nVal );
153 out( ar, stream, nStart, cFillchar );
156 //==================================================================================================
157 Reference< XSingleServiceFactory > loadLibComponentFactory(
158 const OUString & rLibName, const OUString & rImplName,
159 const Reference< XMultiServiceFactory > & xSF, const Reference< XRegistryKey > & xKey )
161 Reference< XSingleServiceFactory > xRet;
163 OUStringBuffer aLibNameBuf( 32 );
164 #ifdef SAL_UNX
165 aLibNameBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM("lib") );
166 aLibNameBuf.append( rLibName );
167 aLibNameBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM(".so") );
168 #else
169 aLibNameBuf.append( rLibName );
170 aLibNameBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM(".dll") );
171 #endif
172 OUString aLibName( aLibNameBuf.makeStringAndClear() );
173 oslModule lib = osl_loadModule( aLibName.pData, SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL );
175 if (lib)
177 void * pSym;
179 // ========================= LATEST VERSION =========================
180 OUString aGetEnvName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETENV) );
181 if (pSym = osl_getSymbol( lib, aGetEnvName.pData ))
183 uno_Environment * pCurrentEnv = 0;
184 uno_Environment * pEnv = 0;
185 const sal_Char * pEnvTypeName = 0;
186 (*((component_getImplementationEnvironmentFunc)pSym))( &pEnvTypeName, &pEnv );
188 sal_Bool bNeedsMapping =
189 (pEnv || 0 != rtl_str_compare( pEnvTypeName, CPPU_CURRENT_LANGUAGE_BINDING_NAME ));
191 OUString aEnvTypeName( OUString::createFromAscii( pEnvTypeName ) );
193 if (bNeedsMapping)
195 if (! pEnv)
196 uno_getEnvironment( &pEnv, aEnvTypeName.pData, 0 );
197 if (pEnv)
199 OUString aCppEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) );
200 uno_getEnvironment( &pCurrentEnv, aCppEnvTypeName.pData, 0 );
201 if (pCurrentEnv)
202 bNeedsMapping = (pEnv != pCurrentEnv);
206 OUString aGetFactoryName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETFACTORY) );
207 if (pSym = osl_getSymbol( lib, aGetFactoryName.pData ))
209 OString aImplName( OUStringToOString( rImplName, RTL_TEXTENCODING_ASCII_US ) );
211 if (bNeedsMapping)
213 if (pEnv && pCurrentEnv)
215 Mapping aCurrent2Env( pCurrentEnv, pEnv );
216 Mapping aEnv2Current( pEnv, pCurrentEnv );
218 if (aCurrent2Env.is() && aEnv2Current.is())
220 void * pSMgr = aCurrent2Env.mapInterface(
221 xSF.get(), ::getCppuType( (const Reference< XMultiServiceFactory > *)0 ) );
222 void * pKey = aCurrent2Env.mapInterface(
223 xKey.get(), ::getCppuType( (const Reference< XRegistryKey > *)0 ) );
225 void * pSSF = (*((component_getFactoryFunc)pSym))(
226 aImplName.getStr(), pSMgr, pKey );
228 if (pKey)
229 (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pKey );
230 if (pSMgr)
231 (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pSMgr );
233 if (pSSF)
235 aEnv2Current.mapInterface(
236 reinterpret_cast< void ** >( &xRet ),
237 pSSF, ::getCppuType( (const Reference< XSingleServiceFactory > *)0 ) );
238 (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pSSF );
243 else
245 XSingleServiceFactory * pRet = (XSingleServiceFactory *)
246 (*((component_getFactoryFunc)pSym))(
247 aImplName.getStr(), xSF.get(), xKey.get() );
248 if (pRet)
250 xRet = pRet;
251 pRet->release();
256 if (pEnv)
257 (*pEnv->release)( pEnv );
258 if (pCurrentEnv)
259 (*pCurrentEnv->release)( pCurrentEnv );
262 // ========================= PREVIOUS VERSION =========================
263 else
265 OUString aGetFactoryName( RTL_CONSTASCII_USTRINGPARAM(CREATE_COMPONENT_FACTORY_FUNCTION) );
266 if (pSym = osl_getSymbol( lib, aGetFactoryName.pData ))
268 OUString aCppEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) );
269 OUString aUnoEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO) );
270 Mapping aUno2Cpp( aUnoEnvTypeName, aCppEnvTypeName );
271 Mapping aCpp2Uno( aCppEnvTypeName, aUnoEnvTypeName );
272 OSL_ENSURE( aUno2Cpp.is() && aCpp2Uno.is(), "### cannot get uno mappings!" );
274 if (aUno2Cpp.is() && aCpp2Uno.is())
276 uno_Interface * pUComponentFactory = 0;
278 uno_Interface * pUSFactory = (uno_Interface *)aCpp2Uno.mapInterface(
279 xSF.get(), ::getCppuType( (const Reference< XMultiServiceFactory > *)0 ) );
280 uno_Interface * pUKey = (uno_Interface *)aCpp2Uno.mapInterface(
281 xKey.get(), ::getCppuType( (const Reference< XRegistryKey > *)0 ) );
283 pUComponentFactory = (*((CreateComponentFactoryFunc)pSym))(
284 rImplName.getStr(), pUSFactory, pUKey );
286 if (pUKey)
287 (*pUKey->release)( pUKey );
288 if (pUSFactory)
289 (*pUSFactory->release)( pUSFactory );
291 if (pUComponentFactory)
293 XSingleServiceFactory * pXFactory =
294 (XSingleServiceFactory *)aUno2Cpp.mapInterface(
295 pUComponentFactory, ::getCppuType( (const Reference< XSingleServiceFactory > *)0 ) );
296 (*pUComponentFactory->release)( pUComponentFactory );
298 if (pXFactory)
300 xRet = pXFactory;
301 pXFactory->release();
308 if (! xRet.is())
309 osl_unloadModule( lib );
312 return xRet;
314 //--------------------------------------------------------------------------------------------------
315 template< class T >
316 static void createInstance( Reference< T > & rxOut,
317 const Reference< XMultiServiceFactory > & xMgr,
318 const OUString & rServiceName )
319 throw (RuntimeException)
321 Reference< XInterface > x( xMgr->createInstance( rServiceName ), UNO_QUERY );
323 if (! x.is())
325 static sal_Bool s_bSet = sal_False;
326 if (! s_bSet)
328 MutexGuard aGuard( Mutex::getGlobalMutex() );
329 if (! s_bSet)
331 Reference< XSet > xSet( xMgr, UNO_QUERY );
332 if (xSet.is())
334 // acceptor
335 xSet->insert( makeAny( loadLibComponentFactory(
336 OUString("acceptor"),
337 OUString("com.sun.star.comp.stoc.Acceptor"),
338 xMgr, Reference< XRegistryKey >() ) ) );
339 // connector
340 xSet->insert( makeAny( loadLibComponentFactory(
341 OUString("connectr"),
342 OUString("com.sun.star.comp.stoc.Connector"),
343 xMgr, Reference< XRegistryKey >() ) ) );
344 // iiop bridge
345 xSet->insert( makeAny( loadLibComponentFactory(
346 OUString("remotebridge"),
347 OUString("com.sun.star.bridge.Bridge.various"),
348 xMgr, Reference< XRegistryKey >() ) ) );
349 // bridge factory
350 xSet->insert( makeAny( loadLibComponentFactory(
351 OUString("brdgfctr"),
352 OUString("com.sun.star.comp.stoc.BridgeFactory"),
353 xMgr, Reference< XRegistryKey >() ) ) );
354 // uno url resolver
355 xSet->insert( makeAny( loadLibComponentFactory(
356 OUString("uuresolver"),
357 OUString("com.sun.star.comp.bridge.UnoUrlResolver"),
358 xMgr, Reference< XRegistryKey >() ) ) );
359 // java loader
360 // xSet->insert( makeAny( loadLibComponentFactory(
361 // OUString("javaloader"),
362 // OUString("com.sun.star.comp.stoc.JavaComponentLoader"),
363 // xMgr, Reference< XRegistryKey >() ) ) );
365 s_bSet = sal_True;
368 x = xMgr->createInstance( rServiceName );
371 if (! x.is())
373 OUStringBuffer buf( 64 );
374 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("cannot get service instance \"") );
375 buf.append( rServiceName );
376 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
377 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
380 rxOut = Reference< T >::query( x );
381 if (! rxOut.is())
383 OUStringBuffer buf( 64 );
384 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("service instance \"") );
385 buf.append( rServiceName );
386 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" does not support demanded interface \"") );
387 const Type & rType = ::getCppuType( (const Reference< T > *)0 );
388 buf.append( rType.getTypeName() );
389 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
390 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
394 //--------------------------------------------------------------------------------------------------
395 inline static Sequence< OUString > getSupportedServiceNames()
397 OUString aName( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME) );
398 return Sequence< OUString >( &aName, 1 );
401 //==================================================================================================
402 class TestImpl : public WeakImplHelper2< XServiceInfo, XMain >
404 Reference< XMultiServiceFactory > _xSMgr;
406 Reference< XInterface > _xDirect;
407 Reference< XInterface > getDirect() throw (Exception);
408 Reference< XInterface > resolveObject( const OUString & rUnoUrl ) throw (Exception);
410 public:
411 TestImpl( const Reference< XMultiServiceFactory > & xSMgr );
412 virtual ~TestImpl();
414 // XServiceInfo
415 virtual OUString SAL_CALL getImplementationName() throw (RuntimeException);
416 virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw (RuntimeException);
417 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (RuntimeException);
419 // XMain
420 virtual sal_Int32 SAL_CALL run( const Sequence< OUString > & rArgs ) throw (RuntimeException);
423 //##################################################################################################
425 //__________________________________________________________________________________________________
426 TestImpl::TestImpl( const Reference< XMultiServiceFactory > & xSMgr )
427 : _xSMgr( xSMgr )
430 //__________________________________________________________________________________________________
431 TestImpl::~TestImpl()
435 //==================================================================================================
436 static Reference< XInterface > SAL_CALL TestImpl_create( const Reference< XMultiServiceFactory > & xSMgr )
438 return Reference< XInterface >( *new TestImpl( xSMgr ) );
441 // XServiceInfo
442 //__________________________________________________________________________________________________
443 OUString TestImpl::getImplementationName()
444 throw (RuntimeException)
446 return OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) );
448 //__________________________________________________________________________________________________
449 sal_Bool TestImpl::supportsService( const OUString & rServiceName )
450 throw (RuntimeException)
452 const Sequence< OUString > & rSNL = getSupportedServiceNames();
453 const OUString * pArray = rSNL.getConstArray();
454 for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
456 if (pArray[nPos] == rServiceName)
457 return sal_True;
459 return sal_False;
461 //__________________________________________________________________________________________________
462 Sequence< OUString > TestImpl::getSupportedServiceNames()
463 throw (RuntimeException)
465 return benchmark_test::getSupportedServiceNames();
468 //__________________________________________________________________________________________________
469 Reference< XInterface > TestImpl::getDirect()
470 throw (Exception)
472 if (! _xDirect.is())
474 MutexGuard aGuard( Mutex::getGlobalMutex() );
475 if (! _xDirect.is())
477 Reference< XSingleServiceFactory > xFac( loadLibComponentFactory(
478 OUString("perfobj"),
479 OUString("com.sun.star.comp.performance.PerformanceTestObject"),
480 _xSMgr, Reference< XRegistryKey >() ) );
481 if (! xFac.is())
482 throw RuntimeException( OUString("no test object available!"), Reference< XInterface >() );
483 _xDirect = xFac->createInstance();
486 return _xDirect;
488 //--------------------------------------------------------------------------------------------------
489 Reference< XInterface > TestImpl::resolveObject( const OUString & rUnoUrl )
490 throw (Exception)
492 Reference< XUnoUrlResolver > xResolver;
493 createInstance(
494 xResolver, _xSMgr,
495 OUString("com.sun.star.bridge.UnoUrlResolver") );
497 Reference< XInterface > xResolvedObject( xResolver->resolve( rUnoUrl ) );
499 if (! xResolvedObject.is())
501 OUStringBuffer buf( 32 );
502 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("cannot resolve object \"") );
503 buf.append( rUnoUrl );
504 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
505 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
508 return xResolvedObject;
511 //==================================================================================================
512 class TimeEntry
514 sal_Int64 nLoop;
515 sal_uInt32 nTicks;
517 public:
518 TimeEntry()
520 TimeEntry( sal_Int64 nLoop_, sal_uInt32 nTicks_ )
521 : nLoop( nLoop_ )
522 , nTicks( nTicks_ )
525 inline double secPerCall() const
526 { return (((double)nTicks) / (nLoop * 1000)); }
528 double ratio( const TimeEntry & rEntry ) const;
530 //__________________________________________________________________________________________________
531 double TimeEntry::ratio( const TimeEntry & rEntry ) const
533 double f = rEntry.nTicks * nLoop;
534 if (f == 0.0)
536 return 0.0;
538 else
540 return (((double)(nTicks * rEntry.nLoop)) / f);
544 //==================================================================================================
545 typedef std::map< std::string, TimeEntry > t_TimeEntryMap;
547 //==================================================================================================
548 struct TimingSheet
550 t_TimeEntryMap _entries;
551 void insert( const sal_Char * pText, sal_Int64 nLoop, sal_uInt32 nTicks );
553 //__________________________________________________________________________________________________
554 void TimingSheet::insert( const sal_Char * pText, sal_Int64 nLoop, sal_uInt32 nTicks )
556 _entries[ pText ] = TimeEntry( nLoop, nTicks );
559 //==================================================================================================
560 typedef boost::unordered_map< std::string, TimingSheet > t_TimingSheetMap;
562 //--------------------------------------------------------------------------------------------------
563 static void benchmark(
564 TimingSheet & rSheet, const Reference< XInterface > & xInstance, sal_Int64 nLoop )
565 throw (Exception)
567 Reference< XPerformanceTest > xBench( xInstance, UNO_QUERY );
568 if (! xBench.is())
569 throw RuntimeException( OUString("illegal test object!"), Reference< XInterface >() );
571 sal_Int64 i;
572 sal_uInt32 tStart, tEnd;
574 const Type & rKnownType = ::getCppuType( (const Reference< XPerformanceTest > *)0 );
575 const Type & rUnKnownType = ::getCppuType( (const Reference< XSet > *)0 );
577 ComplexTypes aDummyStruct;
579 //------------------------------------
580 // oneway calls
581 i = nLoop;
582 tStart = getSystemTicks();
583 while (i--)
584 xBench->async();
585 sal_uInt32 tEndSend = getSystemTicks();
586 xBench->sync();
587 tEnd = getSystemTicks();
588 rSheet.insert( "1a: sending simple oneway calls (no params, no return)", nLoop, tEndSend - tStart );
589 rSheet.insert( "1b: simple oneway calls (no params, no return)", nLoop, tEnd - tStart );
590 // synchron calls
591 i = nLoop;
592 tStart = getSystemTicks();
593 while (i--)
594 xBench->sync();
595 xBench->sync();
596 tEnd = getSystemTicks();
597 rSheet.insert( "1c: simple synchron calls (no params no return)", nLoop+1, tEnd - tStart );
599 // acquire
600 i = nLoop;
601 tStart = getSystemTicks();
602 while (i--)
603 xBench->acquire();
604 tEnd = getSystemTicks();
605 rSheet.insert( "2a: interface acquire() calls", nLoop, tEnd - tStart );
606 // release
607 i = nLoop;
608 tStart = getSystemTicks();
609 while (i--)
610 xBench->release();
611 tEnd = getSystemTicks();
612 rSheet.insert( "2b: interface release() calls", nLoop, tEnd - tStart );
614 // queryInterface() for known type
615 i = nLoop;
616 tStart = getSystemTicks();
617 while (i--)
618 xBench->queryInterface( rKnownType );
619 tEnd = getSystemTicks();
620 rSheet.insert( "2c: interface query for implemented type", nLoop, tEnd - tStart );
621 // queryInterface() for unknown type
622 i = nLoop;
623 tStart = getSystemTicks();
624 while (i--)
625 xBench->queryInterface( rUnKnownType );
626 tEnd = getSystemTicks();
627 rSheet.insert( "2d: interface query for unknown type", nLoop, tEnd - tStart );
629 // create and forget objects
630 Reference< XPerformanceTest > xBench2( xBench );
631 i = nLoop;
632 tStart = getSystemTicks();
633 while (i--)
634 xBench2 = xBench2->createObject();
635 tEnd = getSystemTicks();
636 rSheet.insert( "3a: create and release test objects", nLoop, tEnd - tStart );
638 // hold new objects
639 Sequence< Reference< XInterface > > aSeq( nLoop / 100 );
640 Reference< XInterface > * pSeq = aSeq.getArray();
641 xBench2 = xBench;
642 i = aSeq.getLength();
643 tStart = getSystemTicks();
644 while (i--)
645 pSeq[i] = xBench2 = xBench2->createObject();
646 tEnd = getSystemTicks();
647 rSheet.insert( "3b: create and hold test objects", nLoop, tEnd - tStart );
649 // structs
650 i = nLoop;
651 tStart = getSystemTicks();
652 while (i--)
653 xBench->complex_in( aDummyStruct );
654 tEnd = getSystemTicks();
655 rSheet.insert( "4a: complex_in() calls (in struct; return struct)", nLoop, tEnd - tStart );
656 i = nLoop;
657 tStart = getSystemTicks();
658 while (i--)
659 xBench->complex_inout( aDummyStruct );
660 tEnd = getSystemTicks();
661 rSheet.insert( "4b: complex_inout() calls (inout struct; return struct)", nLoop, tEnd - tStart );
663 i = nLoop;
664 tStart = getSystemTicks();
665 while (i--)
666 xBench->complex_oneway( aDummyStruct );
667 tEnd = getSystemTicks();
668 rSheet.insert( "4c: complex_oneway() oneway calls (in struct)", nLoop, tEnd - tStart );
669 i = nLoop;
670 tStart = getSystemTicks();
671 while (i--)
672 xBench->complex_noreturn( aDummyStruct );
673 tEnd = getSystemTicks();
674 rSheet.insert( "4d: complex_noreturn() calls (in struct)", nLoop, tEnd - tStart );
676 // attributes, get() methods
677 i = nLoop;
678 tStart = getSystemTicks();
679 while (i--)
680 xBench->getLong();
681 tEnd = getSystemTicks();
682 rSheet.insert( "5a: getLong() call", nLoop, tEnd - tStart );
683 i = nLoop;
684 tStart = getSystemTicks();
685 while (i--)
686 xBench->getLong_attr();
687 tEnd = getSystemTicks();
688 rSheet.insert( "5b: get long attribute", nLoop, tEnd - tStart );
690 i = nLoop;
691 tStart = getSystemTicks();
692 while (i--)
693 xBench->setLong( 0 );
694 tEnd = getSystemTicks();
695 rSheet.insert( "5c: setLong() call", nLoop, tEnd - tStart );
696 i = nLoop;
697 tStart = getSystemTicks();
698 while (i--)
699 xBench->setLong_attr( 0 );
700 tEnd = getSystemTicks();
701 rSheet.insert( "5d: set long attribute", nLoop, tEnd - tStart );
703 i = nLoop;
704 tStart = getSystemTicks();
705 while (i--)
706 xBench->getHyper();
707 tEnd = getSystemTicks();
708 rSheet.insert( "5e: getHyper() call", nLoop, tEnd - tStart );
709 i = nLoop;
710 tStart = getSystemTicks();
711 while (i--)
712 xBench->getHyper_attr();
713 tEnd = getSystemTicks();
714 rSheet.insert( "5f: get hyper attribute", nLoop, tEnd - tStart );
716 i = nLoop;
717 tStart = getSystemTicks();
718 while (i--)
719 xBench->setHyper( 0 );
720 tEnd = getSystemTicks();
721 rSheet.insert( "5g: setHyper() call", nLoop, tEnd - tStart );
722 i = nLoop;
723 tStart = getSystemTicks();
724 while (i--)
725 xBench->setHyper_attr( 0 );
726 tEnd = getSystemTicks();
727 rSheet.insert( "5h: set hyper attribute", nLoop, tEnd - tStart );
729 i = nLoop;
730 tStart = getSystemTicks();
731 while (i--)
732 xBench->getFloat();
733 tEnd = getSystemTicks();
734 rSheet.insert( "5i: getFloat() call", nLoop, tEnd - tStart );
735 i = nLoop;
736 tStart = getSystemTicks();
737 while (i--)
738 xBench->getFloat_attr();
739 tEnd = getSystemTicks();
740 rSheet.insert( "5j: get float attribute",nLoop, tEnd - tStart );
742 i = nLoop;
743 tStart = getSystemTicks();
744 while (i--)
745 xBench->setFloat( 0.0 );
746 tEnd = getSystemTicks();
747 rSheet.insert( "5k: setFloat() call", nLoop, tEnd - tStart );
748 i = nLoop;
749 tStart = getSystemTicks();
750 while (i--)
751 xBench->setFloat_attr( 0.0 );
752 tEnd = getSystemTicks();
753 rSheet.insert( "5l: set float attribute", nLoop, tEnd - tStart );
755 i = nLoop;
756 tStart = getSystemTicks();
757 while (i--)
758 xBench->getDouble();
759 tEnd = getSystemTicks();
760 rSheet.insert( "5m: getDouble() call", nLoop, tEnd - tStart );
761 i = nLoop;
762 tStart = getSystemTicks();
763 while (i--)
764 xBench->getDouble_attr();
765 tEnd = getSystemTicks();
766 rSheet.insert( "5n: get double attribute", nLoop, tEnd - tStart );
767 i = nLoop;
768 tStart = getSystemTicks();
769 while (i--)
770 xBench->setDouble( 0.0 );
771 tEnd = getSystemTicks();
772 rSheet.insert( "5o: setDouble() call", nLoop, tEnd - tStart );
773 i = nLoop;
774 tStart = getSystemTicks();
775 while (i--)
776 xBench->setDouble_attr( 0.0 );
777 tEnd = getSystemTicks();
778 rSheet.insert( "5p: set double attribute", nLoop, tEnd - tStart );
780 i = nLoop;
781 tStart = getSystemTicks();
782 while (i--)
783 xBench->getString();
784 tEnd = getSystemTicks();
785 rSheet.insert( "6a: getString() call (empty)", nLoop, tEnd - tStart );
786 i = nLoop;
787 tStart = getSystemTicks();
788 while (i--)
789 xBench->getString_attr();
790 tEnd = getSystemTicks();
791 rSheet.insert( "6b: get empty string attribute", nLoop, tEnd - tStart );
793 i = nLoop;
794 OUString aDummyString;
795 tStart = getSystemTicks();
796 while (i--)
797 xBench->setString( aDummyString );
798 tEnd = getSystemTicks();
799 rSheet.insert( "6c: setString() call (emtpy)", nLoop, tEnd - tStart );
800 i = nLoop;
801 tStart = getSystemTicks();
802 while (i--)
803 xBench->setString_attr( aDummyString );
804 tEnd = getSystemTicks();
805 rSheet.insert( "6d: set empty string attribute", nLoop, tEnd - tStart );
807 i = nLoop;
808 tStart = getSystemTicks();
809 while (i--)
810 xBench->getInterface();
811 tEnd = getSystemTicks();
812 rSheet.insert( "7a: getInterface() call (null)", nLoop, tEnd - tStart );
813 i = nLoop;
814 tStart = getSystemTicks();
815 while (i--)
816 xBench->getInterface_attr();
817 tEnd = getSystemTicks();
818 rSheet.insert( "7b: get interface attribute", nLoop, tEnd - tStart );
820 i = nLoop;
821 Reference< XInterface > aDummyInterface;
822 tStart = getSystemTicks();
823 while (i--)
824 xBench->setInterface( aDummyInterface );
825 tEnd = getSystemTicks();
826 rSheet.insert( "7c: setInterface() call (null)", nLoop, tEnd - tStart );
827 i = nLoop;
828 tStart = getSystemTicks();
829 while (i--)
830 xBench->setInterface_attr( Reference< XInterface >() );
831 tEnd = getSystemTicks();
832 rSheet.insert( "7d: set interface attribute", nLoop, tEnd - tStart );
834 i = nLoop;
835 tStart = getSystemTicks();
836 while (i--)
837 xBench->getAny();
838 tEnd = getSystemTicks();
839 rSheet.insert( "8a: getAny() call (empty)", nLoop, tEnd - tStart );
840 i = nLoop;
841 tStart = getSystemTicks();
842 while (i--)
843 xBench->getAny_attr();
844 tEnd = getSystemTicks();
845 rSheet.insert( "8b: get empty any attribute", nLoop, tEnd - tStart );
847 i = nLoop;
848 Any aDummyAny;
849 tStart = getSystemTicks();
850 while (i--)
851 xBench->setAny( aDummyAny );
852 tEnd = getSystemTicks();
853 rSheet.insert( "8c: setAny() call (empty)", nLoop, tEnd - tStart );
854 i = nLoop;
855 tStart = getSystemTicks();
856 while (i--)
857 xBench->setAny_attr( aDummyAny );
858 tEnd = getSystemTicks();
859 rSheet.insert( "8d: set empty any attribute", nLoop, tEnd - tStart );
861 i = nLoop;
862 tStart = getSystemTicks();
863 while (i--)
864 xBench->getSequence();
865 tEnd = getSystemTicks();
866 rSheet.insert( "9a: getSequence() call (empty)", nLoop, tEnd - tStart );
867 i = nLoop;
868 tStart = getSystemTicks();
869 while (i--)
870 xBench->getSequence_attr();
871 tEnd = getSystemTicks();
872 rSheet.insert( "9b: get empty sequence attribute", nLoop, tEnd - tStart );
873 i = nLoop;
874 Sequence< Reference< XInterface > > aDummySeq;
875 tStart = getSystemTicks();
876 while (i--)
877 xBench->setSequence( aDummySeq );
878 tEnd = getSystemTicks();
879 rSheet.insert( "9c: setSequence() call (empty)", nLoop, tEnd - tStart );
880 i = nLoop;
881 tStart = getSystemTicks();
882 while (i--)
883 xBench->setSequence_attr( aDummySeq );
884 tEnd = getSystemTicks();
885 rSheet.insert( "9d: set empty sequence attribute", nLoop, tEnd - tStart );
887 i = nLoop;
888 tStart = getSystemTicks();
889 while (i--)
890 xBench->getStruct();
891 tEnd = getSystemTicks();
892 rSheet.insert( "Aa: getStruct() call", nLoop, tEnd - tStart );
893 i = nLoop;
894 tStart = getSystemTicks();
895 while (i--)
896 xBench->getStruct_attr();
897 tEnd = getSystemTicks();
898 rSheet.insert( "Ab: get struct attribute", nLoop, tEnd - tStart );
900 i = nLoop;
901 tStart = getSystemTicks();
902 while (i--)
903 xBench->setStruct( aDummyStruct );
904 tEnd = getSystemTicks();
905 rSheet.insert( "Ac: setStruct() call", nLoop, tEnd - tStart );
906 i = nLoop;
907 tStart = getSystemTicks();
908 while (i--)
909 xBench->setStruct_attr( aDummyStruct );
910 tEnd = getSystemTicks();
911 rSheet.insert( "Ad: set struct attribute", nLoop, tEnd - tStart );
913 // load
914 // i = nLoop;
915 // tStart = getSystemTicks();
916 // while (i--)
917 // xBench->setSequence( aSeq );
918 // tEnd = getSystemTicks();
919 // rSheet.insert( "transfer of exisiting objects", nLoop, tEnd - tStart );
921 // exceptions
922 i = nLoop;
923 tStart = getSystemTicks();
924 while (i--)
928 xBench->raiseRuntimeException();
930 catch (RuntimeException &)
934 tEnd = getSystemTicks();
935 rSheet.insert( "Ba: raising RuntimeException", nLoop, tEnd - tStart );
937 //------------------------------------
940 //--------------------------------------------------------------------------------------------------
941 static OUString extractParam( const Sequence< OUString > & rArgs, const OUString & rParam )
943 const OUString * pArgs = rArgs.getConstArray();
944 for ( sal_Int32 nPos = rArgs.getLength(); nPos--; )
946 if (pArgs[nPos].indexOf( rParam ) == 0 &&
947 pArgs[nPos].getLength() > (rParam.getLength()+1))
949 return pArgs[nPos].copy( rParam.getLength() +1 ); // XXX=bla
952 return OUString();
955 const sal_Int32 nMagicNumberDirect = 34000;
957 //XMain
958 //__________________________________________________________________________________________________
959 sal_Int32 TestImpl::run( const Sequence< OUString > & rArgs )
960 throw (RuntimeException)
962 // defaults
963 FILE * stream = stderr;
964 sal_Int64 nLoop = NLOOP;
965 OUString aArg("dms");
969 OUString aLoopStr( extractParam( rArgs, OUString("loop") ) );
970 if (aLoopStr.getLength())
972 sal_Int64 n = aLoopStr.toInt64();
973 if (n > 0)
974 nLoop = n;
977 OUString aDurationStr( extractParam( rArgs , OUString("duration" ) ) );
978 if( aDurationStr.getLength() )
980 sal_Int64 n = aDurationStr.toInt64();
981 if( n >0 )
982 nLoop = nMagicNumberDirect * n;
985 OUString aLogStr( extractParam( rArgs, OUString("log") ) );
986 if (aLogStr.getLength())
988 if (aLogStr.compareToAscii( "stderr" ) == 0)
990 stream = stderr;
992 else if (aLogStr.compareToAscii( "stdout" ) == 0)
994 stream = stdout;
996 else
998 OString aFileName( OUStringToOString( aLogStr, RTL_TEXTENCODING_ASCII_US ) );
999 stream = ::fopen( aFileName.getStr(), "w" );
1000 if (! stream)
1002 OUStringBuffer buf( 32 );
1003 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("cannot open file for writing: \"") );
1004 buf.append( aLogStr );
1005 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
1006 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
1011 OUString aArgStr( extractParam( rArgs, OUString("opt") ) );
1012 if (aArgStr.getLength())
1014 aArg = aArgStr;
1017 if (! rArgs.getLength())
1018 out( "\n> no options given, using defaults" );
1020 // params
1021 out( "\n> opt=" );
1022 out( aArg );
1023 out( " log=" );
1024 if (stream == stderr)
1025 out( "stderr" );
1026 else if (stream == stdout)
1027 out( "stdout loop=" );
1028 else
1029 out( aLogStr );
1030 out( " loop=" );
1031 out( nLoop );
1032 out( "\n" );
1033 t_TimingSheetMap aSheets;
1034 TimingSheet aDirect;
1036 //------------------------------------------------------------------------------------------
1038 if (aArg.indexOf( 'd' ) >= 0)
1040 // in process direct test
1041 sal_uInt32 nStart = getSystemTicks();
1042 benchmark( aDirect, getDirect(), nLoop );
1043 sal_uInt32 nEnd = getSystemTicks();
1044 fprintf( stderr, "Duration (direct in process): %g s\n", (nEnd - nStart)/1000. );
1047 //------------------------------------------------------------------------------------------
1049 if (aArg.indexOf( 'm' ) >= 0)
1051 // in process uno dispatch
1052 Environment aCppEnv, aAnoCppEnv;
1053 OUString aCurrentLanguageBindingName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) );
1054 uno_getEnvironment( reinterpret_cast< uno_Environment ** >( &aCppEnv ),
1055 aCurrentLanguageBindingName.pData, 0 );
1056 // anonymous
1057 uno_createEnvironment( reinterpret_cast< uno_Environment ** >( &aAnoCppEnv ),
1058 aCurrentLanguageBindingName.pData, 0 );
1060 // pseudo mapping uno<->uno: does nothing!
1061 Mapping aMapping( aCppEnv.get(), aAnoCppEnv.get(), OUString("pseudo") );
1062 if (! aMapping.is())
1063 throw RuntimeException( OUString("no pseudo mapping available!"), Reference< XInterface >() );
1065 Reference< XInterface > xMapped;
1066 Reference< XInterface > xDirect( getDirect() );
1067 aMapping.mapInterface( reinterpret_cast< void ** >( &xMapped ), xDirect.get(),
1068 ::getCppuType( &xDirect ) );
1069 if (! xMapped.is())
1070 throw RuntimeException( OUString("mapping object failed!"), Reference< XInterface >() );
1072 sal_uInt32 nStart = getSystemTicks();
1073 benchmark( aSheets[ "mapped in process" ], xMapped, nLoop / 100 );
1074 sal_uInt32 nEnd = getSystemTicks();
1075 fprintf( stderr, "Duration (mapped in process): %g s\n", (nStart - nEnd)/1000. );
1078 //------------------------------------------------------------------------------------------
1080 if (aArg.indexOf( 's' ) >= 0)
1082 // start server process
1083 oslSecurity hSecurity = osl_getCurrentSecurity();
1084 if (! hSecurity)
1085 throw RuntimeException( OUString("cannot get current security handle!"), Reference< XInterface >() );
1087 OUString aArgs[] = {
1088 OUString("-c"),
1089 OUString("com.sun.star.comp.performance.PerformanceTestObject"),
1090 OUString("-l"),
1091 #ifdef SAL_UNX
1092 OUString("libperfobj.so"),
1093 #else
1094 OUString("perfobj.dll"),
1095 #endif
1096 OUString("-r"),
1097 OUString("applicat.rdb"),
1098 OUString("-u"),
1099 OUString("uno:socket,host=localhost,port=6000;iiop;TestRemoteObject"),
1100 OUString("--singleaccept")
1102 rtl_uString * pArgs[] = {
1103 aArgs[0].pData,
1104 aArgs[1].pData,
1105 aArgs[2].pData,
1106 aArgs[3].pData,
1107 aArgs[4].pData,
1108 aArgs[5].pData,
1109 aArgs[6].pData,
1110 aArgs[7].pData,
1111 aArgs[8].pData,
1114 out( "\n> executing: \"uno" );
1115 for ( sal_Int32 nPos = 0; nPos < (sizeof(aArgs) / sizeof(OUString)); ++nPos )
1117 out( " " );
1118 out( aArgs[nPos] );
1120 out( "\" ..." );
1122 oslProcess hProcess = 0;
1123 OUString aUnoExe("uno");
1124 OUString aWorkingDir(".");
1125 osl_executeProcess(
1126 aUnoExe.pData, pArgs, sizeof(aArgs) / sizeof(OUString),
1127 osl_Process_SEARCHPATH | osl_Process_DETACHED | osl_Process_NORMAL,
1128 hSecurity, aWorkingDir.pData, 0, 0, &hProcess );
1130 osl_freeSecurityHandle( hSecurity );
1131 if (! hProcess)
1132 throw RuntimeException( OUString("cannot start server process!"), Reference< XInterface >() );
1133 osl_freeProcessHandle( hProcess );
1135 // wait three seconds
1136 TimeValue threeSeconds;
1137 threeSeconds.Seconds = 3;
1138 osl_waitThread( &threeSeconds );
1140 // connect and resolve outer process object
1141 Reference< XInterface > xResolvedObject( resolveObject( OUString("uno:socket,host=localhost,port=6000;iiop;TestRemoteObject") ) );
1143 benchmark( aSheets[ "remote same host" ], xResolvedObject, nLoop / 300 );
1146 //------------------------------------------------------------------------------------------
1148 if (aArg.indexOf( 'r' ) >= 0)
1150 // remote
1151 OUString aUnoUrl( extractParam( rArgs, OUString("url") ) );
1152 if (! aUnoUrl.getLength())
1153 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("performance test r(emote) needs additional uno url!") ), Reference< XInterface >() );
1155 // connect and resolve outer process object
1156 Reference< XInterface > xResolvedObject( resolveObject( aUnoUrl ) );
1158 sal_Int32 t1 = getSystemTicks();
1159 OString o = OUStringToOString( aUnoUrl, RTL_TEXTENCODING_ASCII_US );
1160 benchmark( aSheets[ o.getStr() ], xResolvedObject, nLoop / 900 );
1161 sal_Int32 t2 = getSystemTicks();
1162 fprintf( stderr, "Duration (%s): %g s\n", o.getStr(),(t2 - t1)/1000. );
1165 //------------------------------------------------------------------------------------------
1167 if (aArg.indexOf( 'j' ) >= 0)
1169 // java
1170 benchmark( aSheets[ "java in process" ],
1171 _xSMgr->createInstance(OUString("com.sun.star.comp.benchmark.JavaTestObject")),
1172 nLoop / 1000 );
1175 //------------------------------------------------------------------------------------------
1176 // dump out tables
1178 out( "\nTimes( ratio to direct in process )", stream );
1179 #if OSL_DEBUG_LEVEL > 1
1180 out ("; compiled with OSL_DEBUG_LEVEL > 1", stream );
1181 #endif
1182 out( ":", stream );
1184 sal_Int32 nPos = 60;
1185 out( "[direct in process]", stream, nPos );
1186 t_TimingSheetMap::const_iterator iSheets( aSheets.begin() );
1187 for ( ; iSheets != aSheets.end(); ++iSheets )
1189 nPos += 40;
1190 out( "[", stream, nPos );
1191 out( (*iSheets).first.c_str(), stream );
1192 out( "]", stream );
1194 for ( t_TimeEntryMap::const_iterator iTopics( aDirect._entries.begin() );
1195 iTopics != aDirect._entries.end(); ++iTopics )
1197 const std::string & rTopic = (*iTopics).first;
1199 out( "\n", stream );
1200 out( rTopic.c_str(), stream );
1202 out( ":", stream, 58, '.' );
1204 sal_Int32 nPos = 60;
1206 double secs = (*iTopics).second.secPerCall();
1207 if (secs > 0.0)
1209 out( secs * 1000, stream, nPos );
1210 out( "ms", stream );
1212 else
1214 out( "NA", stream, nPos );
1217 iSheets = aSheets.begin();
1218 for ( ; iSheets != aSheets.end(); ++iSheets )
1220 const t_TimeEntryMap::const_iterator iFind( (*iSheets).second._entries.find( rTopic ) );
1221 OSL_ENSURE( iFind != (*iSheets).second._entries.end(), "####" );
1223 nPos += 40;
1225 double secs = (*iFind).second.secPerCall();
1226 if (secs != 0.0)
1228 out( secs * 1000, stream, nPos );
1229 out( "ms", stream );
1231 out( " (", stream );
1232 double ratio = (*iFind).second.ratio( (*iTopics).second );
1233 if (ratio != 0.0)
1235 out( ratio, stream );
1236 out( " x)", stream );
1238 else
1240 out( "NA)", stream );
1243 else
1245 out( "NA", stream, nPos );
1250 catch (Exception & rExc)
1252 if (stream != stderr && stream != stdout)
1253 ::fclose( stream );
1254 throw RuntimeException( rExc.Message, rExc.Context );
1257 if (stream != stderr && stream != stdout)
1258 ::fclose( stream );
1260 out( "\n> done.\n" );
1261 return 0;
1267 //##################################################################################################
1268 //##################################################################################################
1269 //##################################################################################################
1272 extern "C"
1274 //==================================================================================================
1275 sal_Bool SAL_CALL component_writeInfo(
1276 void * pServiceManager, void * pRegistryKey )
1278 if (pRegistryKey)
1282 Reference< XRegistryKey > xNewKey(
1283 reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey(
1284 OUString( RTL_CONSTASCII_USTRINGPARAM("/" IMPLNAME "/UNO/SERVICES") ) ) );
1285 xNewKey->createKey( OUString( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME) ) );
1287 return sal_True;
1289 catch (InvalidRegistryException &)
1291 OSL_FAIL( "### InvalidRegistryException!" );
1294 return sal_False;
1296 //==================================================================================================
1297 SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(
1298 const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
1300 void * pRet = 0;
1302 if (pServiceManager && rtl_str_compare( pImplName, IMPLNAME ) == 0)
1304 Reference< XSingleServiceFactory > xFactory( createSingleFactory(
1305 reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
1306 OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) ),
1307 benchmark_test::TestImpl_create,
1308 benchmark_test::getSupportedServiceNames() ) );
1310 if (xFactory.is())
1312 xFactory->acquire();
1313 pRet = xFactory.get();
1317 return pRet;
1321 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */