1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
33 #include <boost/unordered_map.hpp>
36 #include <osl/diagnose.h>
37 #include <osl/mutex.hxx>
38 #include <osl/module.h>
39 #include <osl/process.h>
40 #include <osl/thread.h>
41 #include <osl/conditn.hxx>
47 #include <sys/times.h>
51 #include <rtl/string.hxx>
52 #include <rtl/strbuf.hxx>
53 #include <rtl/ustrbuf.hxx>
55 #include <uno/environment.hxx>
56 #include <uno/mapping.hxx>
58 #include <cppuhelper/factory.hxx>
59 #include <cppuhelper/implbase2.hxx>
61 #include <com/sun/star/lang/XServiceInfo.hpp>
62 #include <com/sun/star/lang/XComponent.hpp>
63 #include <com/sun/star/lang/XMain.hpp>
64 #include <com/sun/star/lang/XInitialization.hpp>
65 #include <com/sun/star/loader/XImplementationLoader.hpp>
66 #include <com/sun/star/registry/XRegistryKey.hpp>
67 #include <com/sun/star/bridge/XUnoUrlResolver.hpp>
68 #include <com/sun/star/container/XSet.hpp>
69 #include <com/sun/star/test/performance/XPerformanceTest.hpp>
71 #define NLOOP 200000000
75 using namespace com::sun::star::uno
;
76 using namespace com::sun::star::lang
;
77 using namespace com::sun::star::loader
;
78 using namespace com::sun::star::registry
;
79 using namespace com::sun::star::bridge
;
80 using namespace com::sun::star::container
;
81 using namespace com::sun::star::test::performance
;
83 using ::rtl::OUString
;
85 using ::rtl::OUStringToOString
;
87 #define SERVICENAME "com.sun.star.test.performance.PerformanceTest"
88 #define IMPLNAME "com.sun.star.comp.performance.PerformanceTest"
90 namespace benchmark_test
93 static inline sal_uInt32
getSystemTicks()
96 return (sal_uInt32
)GetTickCount();
97 #else // only UNX supported for now
98 static sal_uInt32 nImplTicksPerSecond
= 0;
99 static double dImplTicksPerSecond
;
100 static double dImplTicksULONGMAX
;
103 sal_uInt32 nTicks
= (sal_uInt32
)times( &aTms
);
105 if ( !nImplTicksPerSecond
)
107 nImplTicksPerSecond
= sysconf(_SC_CLK_TCK
);
108 dImplTicksPerSecond
= nImplTicksPerSecond
;
109 dImplTicksULONGMAX
= (double)(sal_uInt32
)ULONG_MAX
;
112 double fTicks
= nTicks
;
114 fTicks
/= dImplTicksPerSecond
;
115 fTicks
= fmod (fTicks
, dImplTicksULONGMAX
);
117 return (sal_uInt32
)fTicks
;
121 //--------------------------------------------------------------------------------------------------
122 static void out( const sal_Char
* pText
, FILE * stream
= stderr
,
123 sal_Int32 nStart
= -1, sal_Char cFillchar
= ' ' )
125 static sal_Int32 s_nPos
= 0;
127 sal_Char ar
[2] = { cFillchar
, 0 };
128 while (s_nPos
< nStart
)
130 ::fprintf( stream
, ar
);
134 ::fprintf( stream
, pText
);
136 for ( const sal_Char
* p
= pText
; *p
; ++p
)
144 //--------------------------------------------------------------------------------------------------
145 static inline void out( const OUString
& rText
, FILE * stream
= stderr
,
146 sal_Int32 nStart
= -1, sal_Char cFillchar
= ' ' )
148 OString
aText( OUStringToOString( rText
, RTL_TEXTENCODING_ASCII_US
) );
149 out( aText
.getStr(), stream
, nStart
, cFillchar
);
151 //--------------------------------------------------------------------------------------------------
152 static inline void out( double fVal
, FILE * stream
= stderr
,
153 sal_Int32 nStart
= -1, sal_Char cFillchar
= ' ' )
156 ::snprintf( ar
, sizeof(ar
), (fVal
< 0.000001 ? "%g" : "%f"), fVal
);
157 out( ar
, stream
, nStart
, cFillchar
);
159 //--------------------------------------------------------------------------------------------------
160 static inline void out( sal_Int64 nVal
, FILE * stream
= stderr
,
161 sal_Int32 nStart
= -1, sal_Char cFillchar
= ' ' )
164 ::snprintf( ar
, sizeof(ar
), "%ld", nVal
);
165 out( ar
, stream
, nStart
, cFillchar
);
168 //==================================================================================================
169 Reference
< XSingleServiceFactory
> loadLibComponentFactory(
170 const OUString
& rLibName
, const OUString
& rImplName
,
171 const Reference
< XMultiServiceFactory
> & xSF
, const Reference
< XRegistryKey
> & xKey
)
173 Reference
< XSingleServiceFactory
> xRet
;
175 OUStringBuffer
aLibNameBuf( 32 );
177 aLibNameBuf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("lib") );
178 aLibNameBuf
.append( rLibName
);
179 aLibNameBuf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(".so") );
181 aLibNameBuf
.append( rLibName
);
182 aLibNameBuf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(".dll") );
184 OUString
aLibName( aLibNameBuf
.makeStringAndClear() );
185 oslModule lib
= osl_loadModule( aLibName
.pData
, SAL_LOADMODULE_LAZY
| SAL_LOADMODULE_GLOBAL
);
191 // ========================= LATEST VERSION =========================
192 OUString
aGetEnvName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETENV
) );
193 if (pSym
= osl_getSymbol( lib
, aGetEnvName
.pData
))
195 uno_Environment
* pCurrentEnv
= 0;
196 uno_Environment
* pEnv
= 0;
197 const sal_Char
* pEnvTypeName
= 0;
198 (*((component_getImplementationEnvironmentFunc
)pSym
))( &pEnvTypeName
, &pEnv
);
200 sal_Bool bNeedsMapping
=
201 (pEnv
|| 0 != rtl_str_compare( pEnvTypeName
, CPPU_CURRENT_LANGUAGE_BINDING_NAME
));
203 OUString
aEnvTypeName( OUString::createFromAscii( pEnvTypeName
) );
208 uno_getEnvironment( &pEnv
, aEnvTypeName
.pData
, 0 );
211 OUString
aCppEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME
) );
212 uno_getEnvironment( &pCurrentEnv
, aCppEnvTypeName
.pData
, 0 );
214 bNeedsMapping
= (pEnv
!= pCurrentEnv
);
218 OUString
aGetFactoryName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETFACTORY
) );
219 if (pSym
= osl_getSymbol( lib
, aGetFactoryName
.pData
))
221 OString
aImplName( OUStringToOString( rImplName
, RTL_TEXTENCODING_ASCII_US
) );
225 if (pEnv
&& pCurrentEnv
)
227 Mapping
aCurrent2Env( pCurrentEnv
, pEnv
);
228 Mapping
aEnv2Current( pEnv
, pCurrentEnv
);
230 if (aCurrent2Env
.is() && aEnv2Current
.is())
232 void * pSMgr
= aCurrent2Env
.mapInterface(
233 xSF
.get(), ::getCppuType( (const Reference
< XMultiServiceFactory
> *)0 ) );
234 void * pKey
= aCurrent2Env
.mapInterface(
235 xKey
.get(), ::getCppuType( (const Reference
< XRegistryKey
> *)0 ) );
237 void * pSSF
= (*((component_getFactoryFunc
)pSym
))(
238 aImplName
.getStr(), pSMgr
, pKey
);
241 (*pEnv
->pExtEnv
->releaseInterface
)( pEnv
->pExtEnv
, pKey
);
243 (*pEnv
->pExtEnv
->releaseInterface
)( pEnv
->pExtEnv
, pSMgr
);
247 aEnv2Current
.mapInterface(
248 reinterpret_cast< void ** >( &xRet
),
249 pSSF
, ::getCppuType( (const Reference
< XSingleServiceFactory
> *)0 ) );
250 (*pEnv
->pExtEnv
->releaseInterface
)( pEnv
->pExtEnv
, pSSF
);
257 XSingleServiceFactory
* pRet
= (XSingleServiceFactory
*)
258 (*((component_getFactoryFunc
)pSym
))(
259 aImplName
.getStr(), xSF
.get(), xKey
.get() );
269 (*pEnv
->release
)( pEnv
);
271 (*pCurrentEnv
->release
)( pCurrentEnv
);
274 // ========================= PREVIOUS VERSION =========================
277 OUString
aGetFactoryName( RTL_CONSTASCII_USTRINGPARAM(CREATE_COMPONENT_FACTORY_FUNCTION
) );
278 if (pSym
= osl_getSymbol( lib
, aGetFactoryName
.pData
))
280 OUString
aCppEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME
) );
281 OUString
aUnoEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO
) );
282 Mapping
aUno2Cpp( aUnoEnvTypeName
, aCppEnvTypeName
);
283 Mapping
aCpp2Uno( aCppEnvTypeName
, aUnoEnvTypeName
);
284 OSL_ENSURE( aUno2Cpp
.is() && aCpp2Uno
.is(), "### cannot get uno mappings!" );
286 if (aUno2Cpp
.is() && aCpp2Uno
.is())
288 uno_Interface
* pUComponentFactory
= 0;
290 uno_Interface
* pUSFactory
= (uno_Interface
*)aCpp2Uno
.mapInterface(
291 xSF
.get(), ::getCppuType( (const Reference
< XMultiServiceFactory
> *)0 ) );
292 uno_Interface
* pUKey
= (uno_Interface
*)aCpp2Uno
.mapInterface(
293 xKey
.get(), ::getCppuType( (const Reference
< XRegistryKey
> *)0 ) );
295 pUComponentFactory
= (*((CreateComponentFactoryFunc
)pSym
))(
296 rImplName
.getStr(), pUSFactory
, pUKey
);
299 (*pUKey
->release
)( pUKey
);
301 (*pUSFactory
->release
)( pUSFactory
);
303 if (pUComponentFactory
)
305 XSingleServiceFactory
* pXFactory
=
306 (XSingleServiceFactory
*)aUno2Cpp
.mapInterface(
307 pUComponentFactory
, ::getCppuType( (const Reference
< XSingleServiceFactory
> *)0 ) );
308 (*pUComponentFactory
->release
)( pUComponentFactory
);
313 pXFactory
->release();
321 osl_unloadModule( lib
);
326 //--------------------------------------------------------------------------------------------------
328 static void createInstance( Reference
< T
> & rxOut
,
329 const Reference
< XMultiServiceFactory
> & xMgr
,
330 const OUString
& rServiceName
)
331 throw (RuntimeException
)
333 Reference
< XInterface
> x( xMgr
->createInstance( rServiceName
), UNO_QUERY
);
337 static sal_Bool s_bSet
= sal_False
;
340 MutexGuard
aGuard( Mutex::getGlobalMutex() );
343 Reference
< XSet
> xSet( xMgr
, UNO_QUERY
);
347 xSet
->insert( makeAny( loadLibComponentFactory(
348 OUString( RTL_CONSTASCII_USTRINGPARAM("acceptor") ),
349 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.Acceptor") ),
350 xMgr
, Reference
< XRegistryKey
>() ) ) );
352 xSet
->insert( makeAny( loadLibComponentFactory(
353 OUString( RTL_CONSTASCII_USTRINGPARAM("connectr") ),
354 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.Connector") ),
355 xMgr
, Reference
< XRegistryKey
>() ) ) );
357 xSet
->insert( makeAny( loadLibComponentFactory(
358 OUString( RTL_CONSTASCII_USTRINGPARAM("remotebridge") ),
359 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.Bridge.various") ),
360 xMgr
, Reference
< XRegistryKey
>() ) ) );
362 xSet
->insert( makeAny( loadLibComponentFactory(
363 OUString( RTL_CONSTASCII_USTRINGPARAM("brdgfctr") ),
364 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.BridgeFactory") ),
365 xMgr
, Reference
< XRegistryKey
>() ) ) );
367 xSet
->insert( makeAny( loadLibComponentFactory(
368 OUString( RTL_CONSTASCII_USTRINGPARAM("uuresolver") ),
369 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.bridge.UnoUrlResolver") ),
370 xMgr
, Reference
< XRegistryKey
>() ) ) );
372 // xSet->insert( makeAny( loadLibComponentFactory(
373 // OUString( RTL_CONSTASCII_USTRINGPARAM("javaloader") ),
374 // OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.JavaComponentLoader") ),
375 // xMgr, Reference< XRegistryKey >() ) ) );
380 x
= xMgr
->createInstance( rServiceName
);
385 OUStringBuffer
buf( 64 );
386 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("cannot get service instance \"") );
387 buf
.append( rServiceName
);
388 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
389 throw RuntimeException( buf
.makeStringAndClear(), Reference
< XInterface
>() );
392 rxOut
= Reference
< T
>::query( x
);
395 OUStringBuffer
buf( 64 );
396 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("service instance \"") );
397 buf
.append( rServiceName
);
398 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" does not support demanded interface \"") );
399 const Type
& rType
= ::getCppuType( (const Reference
< T
> *)0 );
400 buf
.append( rType
.getTypeName() );
401 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
402 throw RuntimeException( buf
.makeStringAndClear(), Reference
< XInterface
>() );
406 //--------------------------------------------------------------------------------------------------
407 inline static Sequence
< OUString
> getSupportedServiceNames()
409 OUString
aName( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME
) );
410 return Sequence
< OUString
>( &aName
, 1 );
413 //==================================================================================================
414 class TestImpl
: public WeakImplHelper2
< XServiceInfo
, XMain
>
416 Reference
< XMultiServiceFactory
> _xSMgr
;
418 Reference
< XInterface
> _xDirect
;
419 Reference
< XInterface
> getDirect() throw (Exception
);
420 Reference
< XInterface
> resolveObject( const OUString
& rUnoUrl
) throw (Exception
);
423 TestImpl( const Reference
< XMultiServiceFactory
> & xSMgr
);
427 virtual OUString SAL_CALL
getImplementationName() throw (RuntimeException
);
428 virtual sal_Bool SAL_CALL
supportsService( const OUString
& rServiceName
) throw (RuntimeException
);
429 virtual Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() throw (RuntimeException
);
432 virtual sal_Int32 SAL_CALL
run( const Sequence
< OUString
> & rArgs
) throw (RuntimeException
);
435 //##################################################################################################
437 //__________________________________________________________________________________________________
438 TestImpl::TestImpl( const Reference
< XMultiServiceFactory
> & xSMgr
)
442 //__________________________________________________________________________________________________
443 TestImpl::~TestImpl()
447 //==================================================================================================
448 static Reference
< XInterface
> SAL_CALL
TestImpl_create( const Reference
< XMultiServiceFactory
> & xSMgr
)
450 return Reference
< XInterface
>( *new TestImpl( xSMgr
) );
454 //__________________________________________________________________________________________________
455 OUString
TestImpl::getImplementationName()
456 throw (RuntimeException
)
458 return OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME
) );
460 //__________________________________________________________________________________________________
461 sal_Bool
TestImpl::supportsService( const OUString
& rServiceName
)
462 throw (RuntimeException
)
464 const Sequence
< OUString
> & rSNL
= getSupportedServiceNames();
465 const OUString
* pArray
= rSNL
.getConstArray();
466 for ( sal_Int32 nPos
= rSNL
.getLength(); nPos
--; )
468 if (pArray
[nPos
] == rServiceName
)
473 //__________________________________________________________________________________________________
474 Sequence
< OUString
> TestImpl::getSupportedServiceNames()
475 throw (RuntimeException
)
477 return benchmark_test::getSupportedServiceNames();
480 //__________________________________________________________________________________________________
481 Reference
< XInterface
> TestImpl::getDirect()
486 MutexGuard
aGuard( Mutex::getGlobalMutex() );
489 Reference
< XSingleServiceFactory
> xFac( loadLibComponentFactory(
490 OUString( RTL_CONSTASCII_USTRINGPARAM("perfobj") ),
491 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.performance.PerformanceTestObject") ),
492 _xSMgr
, Reference
< XRegistryKey
>() ) );
494 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("no test object available!") ), Reference
< XInterface
>() );
495 _xDirect
= xFac
->createInstance();
500 //--------------------------------------------------------------------------------------------------
501 Reference
< XInterface
> TestImpl::resolveObject( const OUString
& rUnoUrl
)
504 Reference
< XUnoUrlResolver
> xResolver
;
507 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.UnoUrlResolver") ) );
509 Reference
< XInterface
> xResolvedObject( xResolver
->resolve( rUnoUrl
) );
511 if (! xResolvedObject
.is())
513 OUStringBuffer
buf( 32 );
514 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("cannot resolve object \"") );
515 buf
.append( rUnoUrl
);
516 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
517 throw RuntimeException( buf
.makeStringAndClear(), Reference
< XInterface
>() );
520 return xResolvedObject
;
523 //==================================================================================================
532 TimeEntry( sal_Int64 nLoop_
, sal_uInt32 nTicks_
)
537 inline double secPerCall() const
538 { return (((double)nTicks
) / (nLoop
* 1000)); }
540 double ratio( const TimeEntry
& rEntry
) const;
542 //__________________________________________________________________________________________________
543 double TimeEntry::ratio( const TimeEntry
& rEntry
) const
545 double f
= rEntry
.nTicks
* nLoop
;
552 return (((double)(nTicks
* rEntry
.nLoop
)) / f
);
556 //==================================================================================================
557 typedef std::map
< std::string
, TimeEntry
> t_TimeEntryMap
;
559 //==================================================================================================
562 t_TimeEntryMap _entries
;
563 void insert( const sal_Char
* pText
, sal_Int64 nLoop
, sal_uInt32 nTicks
);
565 //__________________________________________________________________________________________________
566 void TimingSheet::insert( const sal_Char
* pText
, sal_Int64 nLoop
, sal_uInt32 nTicks
)
568 _entries
[ pText
] = TimeEntry( nLoop
, nTicks
);
571 //==================================================================================================
572 typedef boost::unordered_map
< std::string
, TimingSheet
> t_TimingSheetMap
;
574 //--------------------------------------------------------------------------------------------------
575 static void benchmark(
576 TimingSheet
& rSheet
, const Reference
< XInterface
> & xInstance
, sal_Int64 nLoop
)
579 Reference
< XPerformanceTest
> xBench( xInstance
, UNO_QUERY
);
581 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("illegal test object!") ), Reference
< XInterface
>() );
584 sal_uInt32 tStart
, tEnd
;
586 const Type
& rKnownType
= ::getCppuType( (const Reference
< XPerformanceTest
> *)0 );
587 const Type
& rUnKnownType
= ::getCppuType( (const Reference
< XSet
> *)0 );
589 ComplexTypes aDummyStruct
;
591 //------------------------------------
594 tStart
= getSystemTicks();
597 sal_uInt32 tEndSend
= getSystemTicks();
599 tEnd
= getSystemTicks();
600 rSheet
.insert( "1a: sending simple oneway calls (no params, no return)", nLoop
, tEndSend
- tStart
);
601 rSheet
.insert( "1b: simple oneway calls (no params, no return)", nLoop
, tEnd
- tStart
);
604 tStart
= getSystemTicks();
608 tEnd
= getSystemTicks();
609 rSheet
.insert( "1c: simple synchron calls (no params no return)", nLoop
+1, tEnd
- tStart
);
613 tStart
= getSystemTicks();
616 tEnd
= getSystemTicks();
617 rSheet
.insert( "2a: interface acquire() calls", nLoop
, tEnd
- tStart
);
620 tStart
= getSystemTicks();
623 tEnd
= getSystemTicks();
624 rSheet
.insert( "2b: interface release() calls", nLoop
, tEnd
- tStart
);
626 // queryInterface() for known type
628 tStart
= getSystemTicks();
630 xBench
->queryInterface( rKnownType
);
631 tEnd
= getSystemTicks();
632 rSheet
.insert( "2c: interface query for implemented type", nLoop
, tEnd
- tStart
);
633 // queryInterface() for unknown type
635 tStart
= getSystemTicks();
637 xBench
->queryInterface( rUnKnownType
);
638 tEnd
= getSystemTicks();
639 rSheet
.insert( "2d: interface query for unknown type", nLoop
, tEnd
- tStart
);
641 // create and forget objects
642 Reference
< XPerformanceTest
> xBench2( xBench
);
644 tStart
= getSystemTicks();
646 xBench2
= xBench2
->createObject();
647 tEnd
= getSystemTicks();
648 rSheet
.insert( "3a: create and release test objects", nLoop
, tEnd
- tStart
);
651 Sequence
< Reference
< XInterface
> > aSeq( nLoop
/ 100 );
652 Reference
< XInterface
> * pSeq
= aSeq
.getArray();
654 i
= aSeq
.getLength();
655 tStart
= getSystemTicks();
657 pSeq
[i
] = xBench2
= xBench2
->createObject();
658 tEnd
= getSystemTicks();
659 rSheet
.insert( "3b: create and hold test objects", nLoop
, tEnd
- tStart
);
663 tStart
= getSystemTicks();
665 xBench
->complex_in( aDummyStruct
);
666 tEnd
= getSystemTicks();
667 rSheet
.insert( "4a: complex_in() calls (in struct; return struct)", nLoop
, tEnd
- tStart
);
669 tStart
= getSystemTicks();
671 xBench
->complex_inout( aDummyStruct
);
672 tEnd
= getSystemTicks();
673 rSheet
.insert( "4b: complex_inout() calls (inout struct; return struct)", nLoop
, tEnd
- tStart
);
676 tStart
= getSystemTicks();
678 xBench
->complex_oneway( aDummyStruct
);
679 tEnd
= getSystemTicks();
680 rSheet
.insert( "4c: complex_oneway() oneway calls (in struct)", nLoop
, tEnd
- tStart
);
682 tStart
= getSystemTicks();
684 xBench
->complex_noreturn( aDummyStruct
);
685 tEnd
= getSystemTicks();
686 rSheet
.insert( "4d: complex_noreturn() calls (in struct)", nLoop
, tEnd
- tStart
);
688 // attributes, get() methods
690 tStart
= getSystemTicks();
693 tEnd
= getSystemTicks();
694 rSheet
.insert( "5a: getLong() call", nLoop
, tEnd
- tStart
);
696 tStart
= getSystemTicks();
698 xBench
->getLong_attr();
699 tEnd
= getSystemTicks();
700 rSheet
.insert( "5b: get long attribute", nLoop
, tEnd
- tStart
);
703 tStart
= getSystemTicks();
705 xBench
->setLong( 0 );
706 tEnd
= getSystemTicks();
707 rSheet
.insert( "5c: setLong() call", nLoop
, tEnd
- tStart
);
709 tStart
= getSystemTicks();
711 xBench
->setLong_attr( 0 );
712 tEnd
= getSystemTicks();
713 rSheet
.insert( "5d: set long attribute", nLoop
, tEnd
- tStart
);
716 tStart
= getSystemTicks();
719 tEnd
= getSystemTicks();
720 rSheet
.insert( "5e: getHyper() call", nLoop
, tEnd
- tStart
);
722 tStart
= getSystemTicks();
724 xBench
->getHyper_attr();
725 tEnd
= getSystemTicks();
726 rSheet
.insert( "5f: get hyper attribute", nLoop
, tEnd
- tStart
);
729 tStart
= getSystemTicks();
731 xBench
->setHyper( 0 );
732 tEnd
= getSystemTicks();
733 rSheet
.insert( "5g: setHyper() call", nLoop
, tEnd
- tStart
);
735 tStart
= getSystemTicks();
737 xBench
->setHyper_attr( 0 );
738 tEnd
= getSystemTicks();
739 rSheet
.insert( "5h: set hyper attribute", nLoop
, tEnd
- tStart
);
742 tStart
= getSystemTicks();
745 tEnd
= getSystemTicks();
746 rSheet
.insert( "5i: getFloat() call", nLoop
, tEnd
- tStart
);
748 tStart
= getSystemTicks();
750 xBench
->getFloat_attr();
751 tEnd
= getSystemTicks();
752 rSheet
.insert( "5j: get float attribute",nLoop
, tEnd
- tStart
);
755 tStart
= getSystemTicks();
757 xBench
->setFloat( 0.0 );
758 tEnd
= getSystemTicks();
759 rSheet
.insert( "5k: setFloat() call", nLoop
, tEnd
- tStart
);
761 tStart
= getSystemTicks();
763 xBench
->setFloat_attr( 0.0 );
764 tEnd
= getSystemTicks();
765 rSheet
.insert( "5l: set float attribute", nLoop
, tEnd
- tStart
);
768 tStart
= getSystemTicks();
771 tEnd
= getSystemTicks();
772 rSheet
.insert( "5m: getDouble() call", nLoop
, tEnd
- tStart
);
774 tStart
= getSystemTicks();
776 xBench
->getDouble_attr();
777 tEnd
= getSystemTicks();
778 rSheet
.insert( "5n: get double attribute", nLoop
, tEnd
- tStart
);
780 tStart
= getSystemTicks();
782 xBench
->setDouble( 0.0 );
783 tEnd
= getSystemTicks();
784 rSheet
.insert( "5o: setDouble() call", nLoop
, tEnd
- tStart
);
786 tStart
= getSystemTicks();
788 xBench
->setDouble_attr( 0.0 );
789 tEnd
= getSystemTicks();
790 rSheet
.insert( "5p: set double attribute", nLoop
, tEnd
- tStart
);
793 tStart
= getSystemTicks();
796 tEnd
= getSystemTicks();
797 rSheet
.insert( "6a: getString() call (empty)", nLoop
, tEnd
- tStart
);
799 tStart
= getSystemTicks();
801 xBench
->getString_attr();
802 tEnd
= getSystemTicks();
803 rSheet
.insert( "6b: get empty string attribute", nLoop
, tEnd
- tStart
);
806 OUString aDummyString
;
807 tStart
= getSystemTicks();
809 xBench
->setString( aDummyString
);
810 tEnd
= getSystemTicks();
811 rSheet
.insert( "6c: setString() call (emtpy)", nLoop
, tEnd
- tStart
);
813 tStart
= getSystemTicks();
815 xBench
->setString_attr( aDummyString
);
816 tEnd
= getSystemTicks();
817 rSheet
.insert( "6d: set empty string attribute", nLoop
, tEnd
- tStart
);
820 tStart
= getSystemTicks();
822 xBench
->getInterface();
823 tEnd
= getSystemTicks();
824 rSheet
.insert( "7a: getInterface() call (null)", nLoop
, tEnd
- tStart
);
826 tStart
= getSystemTicks();
828 xBench
->getInterface_attr();
829 tEnd
= getSystemTicks();
830 rSheet
.insert( "7b: get interface attribute", nLoop
, tEnd
- tStart
);
833 Reference
< XInterface
> aDummyInterface
;
834 tStart
= getSystemTicks();
836 xBench
->setInterface( aDummyInterface
);
837 tEnd
= getSystemTicks();
838 rSheet
.insert( "7c: setInterface() call (null)", nLoop
, tEnd
- tStart
);
840 tStart
= getSystemTicks();
842 xBench
->setInterface_attr( Reference
< XInterface
>() );
843 tEnd
= getSystemTicks();
844 rSheet
.insert( "7d: set interface attribute", nLoop
, tEnd
- tStart
);
847 tStart
= getSystemTicks();
850 tEnd
= getSystemTicks();
851 rSheet
.insert( "8a: getAny() call (empty)", nLoop
, tEnd
- tStart
);
853 tStart
= getSystemTicks();
855 xBench
->getAny_attr();
856 tEnd
= getSystemTicks();
857 rSheet
.insert( "8b: get empty any attribute", nLoop
, tEnd
- tStart
);
861 tStart
= getSystemTicks();
863 xBench
->setAny( aDummyAny
);
864 tEnd
= getSystemTicks();
865 rSheet
.insert( "8c: setAny() call (empty)", nLoop
, tEnd
- tStart
);
867 tStart
= getSystemTicks();
869 xBench
->setAny_attr( aDummyAny
);
870 tEnd
= getSystemTicks();
871 rSheet
.insert( "8d: set empty any attribute", nLoop
, tEnd
- tStart
);
874 tStart
= getSystemTicks();
876 xBench
->getSequence();
877 tEnd
= getSystemTicks();
878 rSheet
.insert( "9a: getSequence() call (empty)", nLoop
, tEnd
- tStart
);
880 tStart
= getSystemTicks();
882 xBench
->getSequence_attr();
883 tEnd
= getSystemTicks();
884 rSheet
.insert( "9b: get empty sequence attribute", nLoop
, tEnd
- tStart
);
886 Sequence
< Reference
< XInterface
> > aDummySeq
;
887 tStart
= getSystemTicks();
889 xBench
->setSequence( aDummySeq
);
890 tEnd
= getSystemTicks();
891 rSheet
.insert( "9c: setSequence() call (empty)", nLoop
, tEnd
- tStart
);
893 tStart
= getSystemTicks();
895 xBench
->setSequence_attr( aDummySeq
);
896 tEnd
= getSystemTicks();
897 rSheet
.insert( "9d: set empty sequence attribute", nLoop
, tEnd
- tStart
);
900 tStart
= getSystemTicks();
903 tEnd
= getSystemTicks();
904 rSheet
.insert( "Aa: getStruct() call", nLoop
, tEnd
- tStart
);
906 tStart
= getSystemTicks();
908 xBench
->getStruct_attr();
909 tEnd
= getSystemTicks();
910 rSheet
.insert( "Ab: get struct attribute", nLoop
, tEnd
- tStart
);
913 tStart
= getSystemTicks();
915 xBench
->setStruct( aDummyStruct
);
916 tEnd
= getSystemTicks();
917 rSheet
.insert( "Ac: setStruct() call", nLoop
, tEnd
- tStart
);
919 tStart
= getSystemTicks();
921 xBench
->setStruct_attr( aDummyStruct
);
922 tEnd
= getSystemTicks();
923 rSheet
.insert( "Ad: set struct attribute", nLoop
, tEnd
- tStart
);
927 // tStart = getSystemTicks();
929 // xBench->setSequence( aSeq );
930 // tEnd = getSystemTicks();
931 // rSheet.insert( "transfer of exisiting objects", nLoop, tEnd - tStart );
935 tStart
= getSystemTicks();
940 xBench
->raiseRuntimeException();
942 catch (RuntimeException
&)
946 tEnd
= getSystemTicks();
947 rSheet
.insert( "Ba: raising RuntimeException", nLoop
, tEnd
- tStart
);
949 //------------------------------------
952 //--------------------------------------------------------------------------------------------------
953 static OUString
extractParam( const Sequence
< OUString
> & rArgs
, const OUString
& rParam
)
955 const OUString
* pArgs
= rArgs
.getConstArray();
956 for ( sal_Int32 nPos
= rArgs
.getLength(); nPos
--; )
958 if (pArgs
[nPos
].indexOf( rParam
) == 0 &&
959 pArgs
[nPos
].getLength() > (rParam
.getLength()+1))
961 return pArgs
[nPos
].copy( rParam
.getLength() +1 ); // XXX=bla
967 const sal_Int32 nMagicNumberDirect
= 34000;
970 //__________________________________________________________________________________________________
971 sal_Int32
TestImpl::run( const Sequence
< OUString
> & rArgs
)
972 throw (RuntimeException
)
975 FILE * stream
= stderr
;
976 sal_Int64 nLoop
= NLOOP
;
977 OUString
aArg( RTL_CONSTASCII_USTRINGPARAM("dms") );
981 OUString
aLoopStr( extractParam( rArgs
, OUString( RTL_CONSTASCII_USTRINGPARAM("loop") ) ) );
982 if (aLoopStr
.getLength())
984 sal_Int64 n
= aLoopStr
.toInt64();
989 OUString
aDurationStr( extractParam( rArgs
, OUString( RTL_CONSTASCII_USTRINGPARAM("duration" ) ) ) );
990 if( aDurationStr
.getLength() )
992 sal_Int64 n
= aDurationStr
.toInt64();
994 nLoop
= nMagicNumberDirect
* n
;
997 OUString
aLogStr( extractParam( rArgs
, OUString( RTL_CONSTASCII_USTRINGPARAM("log") ) ) );
998 if (aLogStr
.getLength())
1000 if (aLogStr
.compareToAscii( "stderr" ) == 0)
1004 else if (aLogStr
.compareToAscii( "stdout" ) == 0)
1010 OString
aFileName( OUStringToOString( aLogStr
, RTL_TEXTENCODING_ASCII_US
) );
1011 stream
= ::fopen( aFileName
.getStr(), "w" );
1014 OUStringBuffer
buf( 32 );
1015 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("cannot open file for writing: \"") );
1016 buf
.append( aLogStr
);
1017 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
1018 throw RuntimeException( buf
.makeStringAndClear(), Reference
< XInterface
>() );
1023 OUString
aArgStr( extractParam( rArgs
, OUString( RTL_CONSTASCII_USTRINGPARAM("opt") ) ) );
1024 if (aArgStr
.getLength())
1029 if (! rArgs
.getLength())
1030 out( "\n> no options given, using defaults" );
1036 if (stream
== stderr
)
1038 else if (stream
== stderr
)
1039 out( "stdout loop=" );
1045 t_TimingSheetMap aSheets
;
1046 TimingSheet aDirect
;
1048 //------------------------------------------------------------------------------------------
1050 if (aArg
.indexOf( 'd' ) >= 0)
1052 // in process direct test
1053 sal_uInt32 nStart
= getSystemTicks();
1054 benchmark( aDirect
, getDirect(), nLoop
);
1055 sal_uInt32 nEnd
= getSystemTicks();
1056 fprintf( stderr
, "Duration (direct in process): %g s\n", (nEnd
- nStart
)/1000. );
1059 //------------------------------------------------------------------------------------------
1061 if (aArg
.indexOf( 'm' ) >= 0)
1063 // in process uno dispatch
1064 Environment aCppEnv
, aAnoCppEnv
;
1065 OUString
aCurrentLanguageBindingName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME
) );
1066 uno_getEnvironment( reinterpret_cast< uno_Environment
** >( &aCppEnv
),
1067 aCurrentLanguageBindingName
.pData
, 0 );
1069 uno_createEnvironment( reinterpret_cast< uno_Environment
** >( &aAnoCppEnv
),
1070 aCurrentLanguageBindingName
.pData
, 0 );
1072 // pseudo mapping uno<->uno: does nothing!
1073 Mapping
aMapping( aCppEnv
.get(), aAnoCppEnv
.get(), OUString( RTL_CONSTASCII_USTRINGPARAM("pseudo") ) );
1074 if (! aMapping
.is())
1075 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("no pseudo mapping available!") ), Reference
< XInterface
>() );
1077 Reference
< XInterface
> xMapped
;
1078 Reference
< XInterface
> xDirect( getDirect() );
1079 aMapping
.mapInterface( reinterpret_cast< void ** >( &xMapped
), xDirect
.get(),
1080 ::getCppuType( &xDirect
) );
1082 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("mapping object failed!") ), Reference
< XInterface
>() );
1084 sal_uInt32 nStart
= getSystemTicks();
1085 benchmark( aSheets
[ "mapped in process" ], xMapped
, nLoop
/ 100 );
1086 sal_uInt32 nEnd
= getSystemTicks();
1087 fprintf( stderr
, "Duration (mapped in process): %g s\n", (nStart
- nEnd
)/1000. );
1090 //------------------------------------------------------------------------------------------
1092 if (aArg
.indexOf( 's' ) >= 0)
1094 // start server process
1095 oslSecurity hSecurity
= osl_getCurrentSecurity();
1097 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get current security handle!") ), Reference
< XInterface
>() );
1099 OUString aArgs
[] = {
1100 OUString( RTL_CONSTASCII_USTRINGPARAM("-c") ),
1101 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.performance.PerformanceTestObject") ),
1102 OUString( RTL_CONSTASCII_USTRINGPARAM("-l") ),
1104 OUString( RTL_CONSTASCII_USTRINGPARAM("libperfobj.so") ),
1106 OUString( RTL_CONSTASCII_USTRINGPARAM("perfobj.dll") ),
1108 OUString( RTL_CONSTASCII_USTRINGPARAM("-r") ),
1109 OUString( RTL_CONSTASCII_USTRINGPARAM("applicat.rdb") ),
1110 OUString( RTL_CONSTASCII_USTRINGPARAM("-u") ),
1111 OUString( RTL_CONSTASCII_USTRINGPARAM("uno:socket,host=localhost,port=6000;iiop;TestRemoteObject") ),
1112 OUString( RTL_CONSTASCII_USTRINGPARAM("--singleaccept") )
1114 rtl_uString
* pArgs
[] = {
1126 out( "\n> executing: \"uno" );
1127 for ( sal_Int32 nPos
= 0; nPos
< (sizeof(aArgs
) / sizeof(OUString
)); ++nPos
)
1134 oslProcess hProcess
= 0;
1135 OUString
aUnoExe( RTL_CONSTASCII_USTRINGPARAM("uno") );
1136 OUString
aWorkingDir( RTL_CONSTASCII_USTRINGPARAM(".") );
1138 aUnoExe
.pData
, pArgs
, sizeof(aArgs
) / sizeof(OUString
),
1139 osl_Process_SEARCHPATH
| osl_Process_DETACHED
| osl_Process_NORMAL
,
1140 hSecurity
, aWorkingDir
.pData
, 0, 0, &hProcess
);
1142 osl_freeSecurityHandle( hSecurity
);
1144 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("cannot start server process!") ), Reference
< XInterface
>() );
1145 osl_freeProcessHandle( hProcess
);
1147 // wait three seconds
1148 TimeValue threeSeconds
;
1149 threeSeconds
.Seconds
= 3;
1150 osl_waitThread( &threeSeconds
);
1152 // connect and resolve outer process object
1153 Reference
< XInterface
> xResolvedObject( resolveObject( OUString(
1154 RTL_CONSTASCII_USTRINGPARAM("uno:socket,host=localhost,port=6000;iiop;TestRemoteObject") ) ) );
1156 benchmark( aSheets
[ "remote same host" ], xResolvedObject
, nLoop
/ 300 );
1159 //------------------------------------------------------------------------------------------
1161 if (aArg
.indexOf( 'r' ) >= 0)
1164 OUString
aUnoUrl( extractParam( rArgs
, OUString( RTL_CONSTASCII_USTRINGPARAM("url") ) ) );
1165 if (! aUnoUrl
.getLength())
1166 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("performance test r(emote) needs additional uno url!") ), Reference
< XInterface
>() );
1168 // connect and resolve outer process object
1169 Reference
< XInterface
> xResolvedObject( resolveObject( aUnoUrl
) );
1171 sal_Int32 t1
= getSystemTicks();
1172 OString o
= OUStringToOString( aUnoUrl
, RTL_TEXTENCODING_ASCII_US
);
1173 benchmark( aSheets
[ o
.getStr() ], xResolvedObject
, nLoop
/ 900 );
1174 sal_Int32 t2
= getSystemTicks();
1175 fprintf( stderr
, "Duration (%s): %g s\n", o
.getStr(),(t2
- t1
)/1000. );
1178 //------------------------------------------------------------------------------------------
1180 if (aArg
.indexOf( 'j' ) >= 0)
1183 benchmark( aSheets
[ "java in process" ],
1184 _xSMgr
->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.benchmark.JavaTestObject"))),
1188 //------------------------------------------------------------------------------------------
1191 out( "\nTimes( ratio to direct in process )", stream
);
1192 #if OSL_DEBUG_LEVEL > 1
1193 out ("; compiled with OSL_DEBUG_LEVEL > 1", stream
);
1197 sal_Int32 nPos
= 60;
1198 out( "[direct in process]", stream
, nPos
);
1199 t_TimingSheetMap::const_iterator
iSheets( aSheets
.begin() );
1200 for ( ; iSheets
!= aSheets
.end(); ++iSheets
)
1203 out( "[", stream
, nPos
);
1204 out( (*iSheets
).first
.c_str(), stream
);
1207 for ( t_TimeEntryMap::const_iterator
iTopics( aDirect
._entries
.begin() );
1208 iTopics
!= aDirect
._entries
.end(); ++iTopics
)
1210 const std::string
& rTopic
= (*iTopics
).first
;
1212 out( "\n", stream
);
1213 out( rTopic
.c_str(), stream
);
1215 out( ":", stream
, 58, '.' );
1217 sal_Int32 nPos
= 60;
1219 double secs
= (*iTopics
).second
.secPerCall();
1222 out( secs
* 1000, stream
, nPos
);
1223 out( "ms", stream
);
1227 out( "NA", stream
, nPos
);
1230 iSheets
= aSheets
.begin();
1231 for ( ; iSheets
!= aSheets
.end(); ++iSheets
)
1233 const t_TimeEntryMap::const_iterator
iFind( (*iSheets
).second
._entries
.find( rTopic
) );
1234 OSL_ENSURE( iFind
!= (*iSheets
).second
._entries
.end(), "####" );
1238 double secs
= (*iFind
).second
.secPerCall();
1241 out( secs
* 1000, stream
, nPos
);
1242 out( "ms", stream
);
1244 out( " (", stream
);
1245 double ratio
= (*iFind
).second
.ratio( (*iTopics
).second
);
1248 out( ratio
, stream
);
1249 out( " x)", stream
);
1253 out( "NA)", stream
);
1258 out( "NA", stream
, nPos
);
1263 catch (Exception
& rExc
)
1265 if (stream
!= stderr
&& stream
!= stdout
)
1267 throw RuntimeException( rExc
.Message
, rExc
.Context
);
1270 if (stream
!= stderr
&& stream
!= stdout
)
1273 out( "\n> done.\n" );
1280 //##################################################################################################
1281 //##################################################################################################
1282 //##################################################################################################
1287 //==================================================================================================
1288 sal_Bool SAL_CALL
component_writeInfo(
1289 void * pServiceManager
, void * pRegistryKey
)
1295 Reference
< XRegistryKey
> xNewKey(
1296 reinterpret_cast< XRegistryKey
* >( pRegistryKey
)->createKey(
1297 OUString( RTL_CONSTASCII_USTRINGPARAM("/" IMPLNAME
"/UNO/SERVICES") ) ) );
1298 xNewKey
->createKey( OUString( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME
) ) );
1302 catch (InvalidRegistryException
&)
1304 OSL_FAIL( "### InvalidRegistryException!" );
1309 //==================================================================================================
1310 SAL_DLLPUBLIC_EXPORT
void * SAL_CALL
component_getFactory(
1311 const sal_Char
* pImplName
, void * pServiceManager
, void * pRegistryKey
)
1315 if (pServiceManager
&& rtl_str_compare( pImplName
, IMPLNAME
) == 0)
1317 Reference
< XSingleServiceFactory
> xFactory( createSingleFactory(
1318 reinterpret_cast< XMultiServiceFactory
* >( pServiceManager
),
1319 OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME
) ),
1320 benchmark_test::TestImpl_create
,
1321 benchmark_test::getSupportedServiceNames() ) );
1325 xFactory
->acquire();
1326 pRet
= xFactory
.get();
1334 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */