1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
24 #include <boost/unordered_map.hpp>
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>
38 #include <sys/times.h>
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
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()
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
;
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
;
102 fTicks
/= dImplTicksPerSecond
;
103 fTicks
= fmod (fTicks
, dImplTicksULONGMAX
);
105 return (sal_uInt32
)fTicks
;
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
);
122 ::fprintf( stream
, pText
);
124 for ( const sal_Char
* p
= pText
; *p
; ++p
)
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
= ' ' )
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
= ' ' )
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 );
165 aLibNameBuf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("lib") );
166 aLibNameBuf
.append( rLibName
);
167 aLibNameBuf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(".so") );
169 aLibNameBuf
.append( rLibName
);
170 aLibNameBuf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(".dll") );
172 OUString
aLibName( aLibNameBuf
.makeStringAndClear() );
173 oslModule lib
= osl_loadModule( aLibName
.pData
, SAL_LOADMODULE_LAZY
| SAL_LOADMODULE_GLOBAL
);
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
) );
196 uno_getEnvironment( &pEnv
, aEnvTypeName
.pData
, 0 );
199 OUString
aCppEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME
) );
200 uno_getEnvironment( &pCurrentEnv
, aCppEnvTypeName
.pData
, 0 );
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
) );
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
);
229 (*pEnv
->pExtEnv
->releaseInterface
)( pEnv
->pExtEnv
, pKey
);
231 (*pEnv
->pExtEnv
->releaseInterface
)( pEnv
->pExtEnv
, pSMgr
);
235 aEnv2Current
.mapInterface(
236 reinterpret_cast< void ** >( &xRet
),
237 pSSF
, ::getCppuType( (const Reference
< XSingleServiceFactory
> *)0 ) );
238 (*pEnv
->pExtEnv
->releaseInterface
)( pEnv
->pExtEnv
, pSSF
);
245 XSingleServiceFactory
* pRet
= (XSingleServiceFactory
*)
246 (*((component_getFactoryFunc
)pSym
))(
247 aImplName
.getStr(), xSF
.get(), xKey
.get() );
257 (*pEnv
->release
)( pEnv
);
259 (*pCurrentEnv
->release
)( pCurrentEnv
);
262 // ========================= PREVIOUS VERSION =========================
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
);
287 (*pUKey
->release
)( pUKey
);
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
);
301 pXFactory
->release();
309 osl_unloadModule( lib
);
314 //--------------------------------------------------------------------------------------------------
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
);
325 static sal_Bool s_bSet
= sal_False
;
328 MutexGuard
aGuard( Mutex::getGlobalMutex() );
331 Reference
< XSet
> xSet( xMgr
, UNO_QUERY
);
335 xSet
->insert( makeAny( loadLibComponentFactory(
336 OUString("acceptor"),
337 OUString("com.sun.star.comp.stoc.Acceptor"),
338 xMgr
, Reference
< XRegistryKey
>() ) ) );
340 xSet
->insert( makeAny( loadLibComponentFactory(
341 OUString("connectr"),
342 OUString("com.sun.star.comp.stoc.Connector"),
343 xMgr
, Reference
< XRegistryKey
>() ) ) );
345 xSet
->insert( makeAny( loadLibComponentFactory(
346 OUString("remotebridge"),
347 OUString("com.sun.star.bridge.Bridge.various"),
348 xMgr
, Reference
< XRegistryKey
>() ) ) );
350 xSet
->insert( makeAny( loadLibComponentFactory(
351 OUString("brdgfctr"),
352 OUString("com.sun.star.comp.stoc.BridgeFactory"),
353 xMgr
, Reference
< XRegistryKey
>() ) ) );
355 xSet
->insert( makeAny( loadLibComponentFactory(
356 OUString("uuresolver"),
357 OUString("com.sun.star.comp.bridge.UnoUrlResolver"),
358 xMgr
, Reference
< XRegistryKey
>() ) ) );
360 // xSet->insert( makeAny( loadLibComponentFactory(
361 // OUString("javaloader"),
362 // OUString("com.sun.star.comp.stoc.JavaComponentLoader"),
363 // xMgr, Reference< XRegistryKey >() ) ) );
368 x
= xMgr
->createInstance( rServiceName
);
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
);
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
);
411 TestImpl( const Reference
< XMultiServiceFactory
> & xSMgr
);
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
);
420 virtual sal_Int32 SAL_CALL
run( const Sequence
< OUString
> & rArgs
) throw (RuntimeException
);
423 //##################################################################################################
425 //__________________________________________________________________________________________________
426 TestImpl::TestImpl( const Reference
< XMultiServiceFactory
> & 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
) );
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
)
461 //__________________________________________________________________________________________________
462 Sequence
< OUString
> TestImpl::getSupportedServiceNames()
463 throw (RuntimeException
)
465 return benchmark_test::getSupportedServiceNames();
468 //__________________________________________________________________________________________________
469 Reference
< XInterface
> TestImpl::getDirect()
474 MutexGuard
aGuard( Mutex::getGlobalMutex() );
477 Reference
< XSingleServiceFactory
> xFac( loadLibComponentFactory(
479 OUString("com.sun.star.comp.performance.PerformanceTestObject"),
480 _xSMgr
, Reference
< XRegistryKey
>() ) );
482 throw RuntimeException( OUString("no test object available!"), Reference
< XInterface
>() );
483 _xDirect
= xFac
->createInstance();
488 //--------------------------------------------------------------------------------------------------
489 Reference
< XInterface
> TestImpl::resolveObject( const OUString
& rUnoUrl
)
492 Reference
< XUnoUrlResolver
> xResolver
;
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 //==================================================================================================
520 TimeEntry( sal_Int64 nLoop_
, sal_uInt32 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
;
540 return (((double)(nTicks
* rEntry
.nLoop
)) / f
);
544 //==================================================================================================
545 typedef std::map
< std::string
, TimeEntry
> t_TimeEntryMap
;
547 //==================================================================================================
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
)
567 Reference
< XPerformanceTest
> xBench( xInstance
, UNO_QUERY
);
569 throw RuntimeException( OUString("illegal test object!"), Reference
< XInterface
>() );
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 //------------------------------------
582 tStart
= getSystemTicks();
585 sal_uInt32 tEndSend
= getSystemTicks();
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
);
592 tStart
= getSystemTicks();
596 tEnd
= getSystemTicks();
597 rSheet
.insert( "1c: simple synchron calls (no params no return)", nLoop
+1, tEnd
- tStart
);
601 tStart
= getSystemTicks();
604 tEnd
= getSystemTicks();
605 rSheet
.insert( "2a: interface acquire() calls", nLoop
, tEnd
- tStart
);
608 tStart
= getSystemTicks();
611 tEnd
= getSystemTicks();
612 rSheet
.insert( "2b: interface release() calls", nLoop
, tEnd
- tStart
);
614 // queryInterface() for known type
616 tStart
= getSystemTicks();
618 xBench
->queryInterface( rKnownType
);
619 tEnd
= getSystemTicks();
620 rSheet
.insert( "2c: interface query for implemented type", nLoop
, tEnd
- tStart
);
621 // queryInterface() for unknown type
623 tStart
= getSystemTicks();
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
);
632 tStart
= getSystemTicks();
634 xBench2
= xBench2
->createObject();
635 tEnd
= getSystemTicks();
636 rSheet
.insert( "3a: create and release test objects", nLoop
, tEnd
- tStart
);
639 Sequence
< Reference
< XInterface
> > aSeq( nLoop
/ 100 );
640 Reference
< XInterface
> * pSeq
= aSeq
.getArray();
642 i
= aSeq
.getLength();
643 tStart
= getSystemTicks();
645 pSeq
[i
] = xBench2
= xBench2
->createObject();
646 tEnd
= getSystemTicks();
647 rSheet
.insert( "3b: create and hold test objects", nLoop
, tEnd
- tStart
);
651 tStart
= getSystemTicks();
653 xBench
->complex_in( aDummyStruct
);
654 tEnd
= getSystemTicks();
655 rSheet
.insert( "4a: complex_in() calls (in struct; return struct)", nLoop
, tEnd
- tStart
);
657 tStart
= getSystemTicks();
659 xBench
->complex_inout( aDummyStruct
);
660 tEnd
= getSystemTicks();
661 rSheet
.insert( "4b: complex_inout() calls (inout struct; return struct)", nLoop
, tEnd
- tStart
);
664 tStart
= getSystemTicks();
666 xBench
->complex_oneway( aDummyStruct
);
667 tEnd
= getSystemTicks();
668 rSheet
.insert( "4c: complex_oneway() oneway calls (in struct)", nLoop
, tEnd
- tStart
);
670 tStart
= getSystemTicks();
672 xBench
->complex_noreturn( aDummyStruct
);
673 tEnd
= getSystemTicks();
674 rSheet
.insert( "4d: complex_noreturn() calls (in struct)", nLoop
, tEnd
- tStart
);
676 // attributes, get() methods
678 tStart
= getSystemTicks();
681 tEnd
= getSystemTicks();
682 rSheet
.insert( "5a: getLong() call", nLoop
, tEnd
- tStart
);
684 tStart
= getSystemTicks();
686 xBench
->getLong_attr();
687 tEnd
= getSystemTicks();
688 rSheet
.insert( "5b: get long attribute", nLoop
, tEnd
- tStart
);
691 tStart
= getSystemTicks();
693 xBench
->setLong( 0 );
694 tEnd
= getSystemTicks();
695 rSheet
.insert( "5c: setLong() call", nLoop
, tEnd
- tStart
);
697 tStart
= getSystemTicks();
699 xBench
->setLong_attr( 0 );
700 tEnd
= getSystemTicks();
701 rSheet
.insert( "5d: set long attribute", nLoop
, tEnd
- tStart
);
704 tStart
= getSystemTicks();
707 tEnd
= getSystemTicks();
708 rSheet
.insert( "5e: getHyper() call", nLoop
, tEnd
- tStart
);
710 tStart
= getSystemTicks();
712 xBench
->getHyper_attr();
713 tEnd
= getSystemTicks();
714 rSheet
.insert( "5f: get hyper attribute", nLoop
, tEnd
- tStart
);
717 tStart
= getSystemTicks();
719 xBench
->setHyper( 0 );
720 tEnd
= getSystemTicks();
721 rSheet
.insert( "5g: setHyper() call", nLoop
, tEnd
- tStart
);
723 tStart
= getSystemTicks();
725 xBench
->setHyper_attr( 0 );
726 tEnd
= getSystemTicks();
727 rSheet
.insert( "5h: set hyper attribute", nLoop
, tEnd
- tStart
);
730 tStart
= getSystemTicks();
733 tEnd
= getSystemTicks();
734 rSheet
.insert( "5i: getFloat() call", nLoop
, tEnd
- tStart
);
736 tStart
= getSystemTicks();
738 xBench
->getFloat_attr();
739 tEnd
= getSystemTicks();
740 rSheet
.insert( "5j: get float attribute",nLoop
, tEnd
- tStart
);
743 tStart
= getSystemTicks();
745 xBench
->setFloat( 0.0 );
746 tEnd
= getSystemTicks();
747 rSheet
.insert( "5k: setFloat() call", nLoop
, tEnd
- tStart
);
749 tStart
= getSystemTicks();
751 xBench
->setFloat_attr( 0.0 );
752 tEnd
= getSystemTicks();
753 rSheet
.insert( "5l: set float attribute", nLoop
, tEnd
- tStart
);
756 tStart
= getSystemTicks();
759 tEnd
= getSystemTicks();
760 rSheet
.insert( "5m: getDouble() call", nLoop
, tEnd
- tStart
);
762 tStart
= getSystemTicks();
764 xBench
->getDouble_attr();
765 tEnd
= getSystemTicks();
766 rSheet
.insert( "5n: get double attribute", nLoop
, tEnd
- tStart
);
768 tStart
= getSystemTicks();
770 xBench
->setDouble( 0.0 );
771 tEnd
= getSystemTicks();
772 rSheet
.insert( "5o: setDouble() call", nLoop
, tEnd
- tStart
);
774 tStart
= getSystemTicks();
776 xBench
->setDouble_attr( 0.0 );
777 tEnd
= getSystemTicks();
778 rSheet
.insert( "5p: set double attribute", nLoop
, tEnd
- tStart
);
781 tStart
= getSystemTicks();
784 tEnd
= getSystemTicks();
785 rSheet
.insert( "6a: getString() call (empty)", nLoop
, tEnd
- tStart
);
787 tStart
= getSystemTicks();
789 xBench
->getString_attr();
790 tEnd
= getSystemTicks();
791 rSheet
.insert( "6b: get empty string attribute", nLoop
, tEnd
- tStart
);
794 OUString aDummyString
;
795 tStart
= getSystemTicks();
797 xBench
->setString( aDummyString
);
798 tEnd
= getSystemTicks();
799 rSheet
.insert( "6c: setString() call (emtpy)", nLoop
, tEnd
- tStart
);
801 tStart
= getSystemTicks();
803 xBench
->setString_attr( aDummyString
);
804 tEnd
= getSystemTicks();
805 rSheet
.insert( "6d: set empty string attribute", nLoop
, tEnd
- tStart
);
808 tStart
= getSystemTicks();
810 xBench
->getInterface();
811 tEnd
= getSystemTicks();
812 rSheet
.insert( "7a: getInterface() call (null)", nLoop
, tEnd
- tStart
);
814 tStart
= getSystemTicks();
816 xBench
->getInterface_attr();
817 tEnd
= getSystemTicks();
818 rSheet
.insert( "7b: get interface attribute", nLoop
, tEnd
- tStart
);
821 Reference
< XInterface
> aDummyInterface
;
822 tStart
= getSystemTicks();
824 xBench
->setInterface( aDummyInterface
);
825 tEnd
= getSystemTicks();
826 rSheet
.insert( "7c: setInterface() call (null)", nLoop
, tEnd
- tStart
);
828 tStart
= getSystemTicks();
830 xBench
->setInterface_attr( Reference
< XInterface
>() );
831 tEnd
= getSystemTicks();
832 rSheet
.insert( "7d: set interface attribute", nLoop
, tEnd
- tStart
);
835 tStart
= getSystemTicks();
838 tEnd
= getSystemTicks();
839 rSheet
.insert( "8a: getAny() call (empty)", nLoop
, tEnd
- tStart
);
841 tStart
= getSystemTicks();
843 xBench
->getAny_attr();
844 tEnd
= getSystemTicks();
845 rSheet
.insert( "8b: get empty any attribute", nLoop
, tEnd
- tStart
);
849 tStart
= getSystemTicks();
851 xBench
->setAny( aDummyAny
);
852 tEnd
= getSystemTicks();
853 rSheet
.insert( "8c: setAny() call (empty)", nLoop
, tEnd
- tStart
);
855 tStart
= getSystemTicks();
857 xBench
->setAny_attr( aDummyAny
);
858 tEnd
= getSystemTicks();
859 rSheet
.insert( "8d: set empty any attribute", nLoop
, tEnd
- tStart
);
862 tStart
= getSystemTicks();
864 xBench
->getSequence();
865 tEnd
= getSystemTicks();
866 rSheet
.insert( "9a: getSequence() call (empty)", nLoop
, tEnd
- tStart
);
868 tStart
= getSystemTicks();
870 xBench
->getSequence_attr();
871 tEnd
= getSystemTicks();
872 rSheet
.insert( "9b: get empty sequence attribute", nLoop
, tEnd
- tStart
);
874 Sequence
< Reference
< XInterface
> > aDummySeq
;
875 tStart
= getSystemTicks();
877 xBench
->setSequence( aDummySeq
);
878 tEnd
= getSystemTicks();
879 rSheet
.insert( "9c: setSequence() call (empty)", nLoop
, tEnd
- tStart
);
881 tStart
= getSystemTicks();
883 xBench
->setSequence_attr( aDummySeq
);
884 tEnd
= getSystemTicks();
885 rSheet
.insert( "9d: set empty sequence attribute", nLoop
, tEnd
- tStart
);
888 tStart
= getSystemTicks();
891 tEnd
= getSystemTicks();
892 rSheet
.insert( "Aa: getStruct() call", nLoop
, tEnd
- tStart
);
894 tStart
= getSystemTicks();
896 xBench
->getStruct_attr();
897 tEnd
= getSystemTicks();
898 rSheet
.insert( "Ab: get struct attribute", nLoop
, tEnd
- tStart
);
901 tStart
= getSystemTicks();
903 xBench
->setStruct( aDummyStruct
);
904 tEnd
= getSystemTicks();
905 rSheet
.insert( "Ac: setStruct() call", nLoop
, tEnd
- tStart
);
907 tStart
= getSystemTicks();
909 xBench
->setStruct_attr( aDummyStruct
);
910 tEnd
= getSystemTicks();
911 rSheet
.insert( "Ad: set struct attribute", nLoop
, tEnd
- tStart
);
915 // tStart = getSystemTicks();
917 // xBench->setSequence( aSeq );
918 // tEnd = getSystemTicks();
919 // rSheet.insert( "transfer of exisiting objects", nLoop, tEnd - tStart );
923 tStart
= getSystemTicks();
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
955 const sal_Int32 nMagicNumberDirect
= 34000;
958 //__________________________________________________________________________________________________
959 sal_Int32
TestImpl::run( const Sequence
< OUString
> & rArgs
)
960 throw (RuntimeException
)
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();
977 OUString
aDurationStr( extractParam( rArgs
, OUString("duration" ) ) );
978 if( aDurationStr
.getLength() )
980 sal_Int64 n
= aDurationStr
.toInt64();
982 nLoop
= nMagicNumberDirect
* n
;
985 OUString
aLogStr( extractParam( rArgs
, OUString("log") ) );
986 if (aLogStr
.getLength())
988 if (aLogStr
.compareToAscii( "stderr" ) == 0)
992 else if (aLogStr
.compareToAscii( "stdout" ) == 0)
998 OString
aFileName( OUStringToOString( aLogStr
, RTL_TEXTENCODING_ASCII_US
) );
999 stream
= ::fopen( aFileName
.getStr(), "w" );
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())
1017 if (! rArgs
.getLength())
1018 out( "\n> no options given, using defaults" );
1024 if (stream
== stderr
)
1026 else if (stream
== stdout
)
1027 out( "stdout loop=" );
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 );
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
) );
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();
1085 throw RuntimeException( OUString("cannot get current security handle!"), Reference
< XInterface
>() );
1087 OUString aArgs
[] = {
1089 OUString("com.sun.star.comp.performance.PerformanceTestObject"),
1092 OUString("libperfobj.so"),
1094 OUString("perfobj.dll"),
1097 OUString("applicat.rdb"),
1099 OUString("uno:socket,host=localhost,port=6000;iiop;TestRemoteObject"),
1100 OUString("--singleaccept")
1102 rtl_uString
* pArgs
[] = {
1114 out( "\n> executing: \"uno" );
1115 for ( sal_Int32 nPos
= 0; nPos
< (sizeof(aArgs
) / sizeof(OUString
)); ++nPos
)
1122 oslProcess hProcess
= 0;
1123 OUString
aUnoExe("uno");
1124 OUString
aWorkingDir(".");
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
);
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)
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)
1170 benchmark( aSheets
[ "java in process" ],
1171 _xSMgr
->createInstance(OUString("com.sun.star.comp.benchmark.JavaTestObject")),
1175 //------------------------------------------------------------------------------------------
1178 out( "\nTimes( ratio to direct in process )", stream
);
1179 #if OSL_DEBUG_LEVEL > 1
1180 out ("; compiled with OSL_DEBUG_LEVEL > 1", 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
)
1190 out( "[", stream
, nPos
);
1191 out( (*iSheets
).first
.c_str(), 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();
1209 out( secs
* 1000, stream
, nPos
);
1210 out( "ms", stream
);
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(), "####" );
1225 double secs
= (*iFind
).second
.secPerCall();
1228 out( secs
* 1000, stream
, nPos
);
1229 out( "ms", stream
);
1231 out( " (", stream
);
1232 double ratio
= (*iFind
).second
.ratio( (*iTopics
).second
);
1235 out( ratio
, stream
);
1236 out( " x)", stream
);
1240 out( "NA)", stream
);
1245 out( "NA", stream
, nPos
);
1250 catch (Exception
& rExc
)
1252 if (stream
!= stderr
&& stream
!= stdout
)
1254 throw RuntimeException( rExc
.Message
, rExc
.Context
);
1257 if (stream
!= stderr
&& stream
!= stdout
)
1260 out( "\n> done.\n" );
1267 //##################################################################################################
1268 //##################################################################################################
1269 //##################################################################################################
1274 //==================================================================================================
1275 sal_Bool SAL_CALL
component_writeInfo(
1276 void * pServiceManager
, void * 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
) ) );
1289 catch (InvalidRegistryException
&)
1291 OSL_FAIL( "### InvalidRegistryException!" );
1296 //==================================================================================================
1297 SAL_DLLPUBLIC_EXPORT
void * SAL_CALL
component_getFactory(
1298 const sal_Char
* pImplName
, void * pServiceManager
, void * pRegistryKey
)
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() ) );
1312 xFactory
->acquire();
1313 pRet
= xFactory
.get();
1321 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */