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 .
25 #include <unordered_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.hxx>
32 #include <osl/conditn.hxx>
36 #if !defined WIN32_LEAN_AND_MEAN
37 # define WIN32_LEAN_AND_MEAN
41 #include <sys/times.h>
45 #include <rtl/string.hxx>
46 #include <rtl/strbuf.hxx>
47 #include <rtl/ustrbuf.hxx>
49 #include <uno/environment.hxx>
50 #include <uno/lbnames.h>
51 #include <uno/mapping.hxx>
53 #include <cppuhelper/factory.hxx>
54 #include <cppuhelper/implbase.hxx>
56 #include <com/sun/star/lang/XServiceInfo.hpp>
57 #include <com/sun/star/lang/XComponent.hpp>
58 #include <com/sun/star/lang/XMain.hpp>
59 #include <com/sun/star/lang/XInitialization.hpp>
60 #include <com/sun/star/loader/XImplementationLoader.hpp>
61 #include <com/sun/star/registry/XRegistryKey.hpp>
62 #include <com/sun/star/bridge/XUnoUrlResolver.hpp>
63 #include <com/sun/star/container/XSet.hpp>
64 #include <com/sun/star/test/performance/XPerformanceTest.hpp>
66 #define NLOOP 200000000
70 using namespace com::sun::star::uno
;
71 using namespace com::sun::star::lang
;
72 using namespace com::sun::star::loader
;
73 using namespace com::sun::star::registry
;
74 using namespace com::sun::star::bridge
;
75 using namespace com::sun::star::container
;
76 using namespace com::sun::star::test::performance
;
79 #define SERVICENAME "com.sun.star.test.performance.PerformanceTest"
80 #define IMPLNAME "com.sun.star.comp.performance.PerformanceTest"
82 namespace benchmark_test
85 static inline sal_uInt32
getSystemTicks()
88 return (sal_uInt32
)GetTickCount();
89 #else // only UNX supported for now
90 static sal_uInt32 nImplTicksPerSecond
= 0;
91 static double dImplTicksPerSecond
;
92 static double dImplTicksULONGMAX
;
95 sal_uInt32 nTicks
= (sal_uInt32
)times( &aTms
);
97 if ( !nImplTicksPerSecond
)
99 nImplTicksPerSecond
= sysconf(_SC_CLK_TCK
);
100 dImplTicksPerSecond
= nImplTicksPerSecond
;
101 dImplTicksULONGMAX
= (double)(sal_uInt32
)ULONG_MAX
;
104 double fTicks
= nTicks
;
106 fTicks
/= dImplTicksPerSecond
;
107 fTicks
= fmod (fTicks
, dImplTicksULONGMAX
);
109 return (sal_uInt32
)fTicks
;
114 static void out( const char * pText
, FILE * stream
= stderr
,
115 sal_Int32 nStart
= -1, char cFillchar
= ' ' )
117 static sal_Int32 s_nPos
= 0;
119 char ar
[2] = { cFillchar
, 0 };
120 while (s_nPos
< nStart
)
122 ::fprintf( stream
, ar
);
126 ::fprintf( stream
, pText
);
128 for ( const char * p
= pText
; *p
; ++p
)
137 static inline void out( const OUString
& rText
, FILE * stream
= stderr
,
138 sal_Int32 nStart
= -1, char cFillchar
= ' ' )
140 OString
aText( OUStringToOString( rText
, RTL_TEXTENCODING_ASCII_US
) );
141 out( aText
.getStr(), stream
, nStart
, cFillchar
);
144 static inline void out( double fVal
, FILE * stream
= stderr
,
145 sal_Int32 nStart
= -1, char cFillchar
= ' ' )
148 ::snprintf( ar
, sizeof(ar
), (fVal
< 0.000001 ? "%g" : "%f"), fVal
);
149 out( ar
, stream
, nStart
, cFillchar
);
152 static inline void out( sal_Int64 nVal
, FILE * stream
= stderr
,
153 sal_Int32 nStart
= -1, char cFillchar
= ' ' )
156 ::snprintf( ar
, sizeof(ar
), "%" SAL_PRIdINT64
, nVal
);
157 out( ar
, stream
, nStart
, cFillchar
);
161 Reference
< XSingleServiceFactory
> loadLibComponentFactory(
162 const OUString
& rLibName
, const OUString
& rImplName
,
163 const Reference
< XMultiServiceFactory
> & xSF
, const Reference
< XRegistryKey
> & xKey
)
165 Reference
< XSingleServiceFactory
> xRet
;
167 OUStringBuffer
aLibNameBuf( 32 );
169 aLibNameBuf
.append( "lib" );
170 aLibNameBuf
.append( rLibName
);
171 aLibNameBuf
.append( ".so" );
173 aLibNameBuf
.append( rLibName
);
174 aLibNameBuf
.append( ".dll" );
176 OUString
aLibName( aLibNameBuf
.makeStringAndClear() );
177 oslModule lib
= osl_loadModule( aLibName
.pData
, SAL_LOADMODULE_LAZY
| SAL_LOADMODULE_GLOBAL
);
183 // ========================= LATEST VERSION =========================
184 OUString
aGetEnvName( COMPONENT_GETENV
);
185 if (pSym
= osl_getSymbol( lib
, aGetEnvName
.pData
))
187 uno_Environment
* pCurrentEnv
= 0;
188 uno_Environment
* pEnv
= 0;
189 const char * pEnvTypeName
= 0;
190 (*((component_getImplementationEnvironmentFunc
)pSym
))( &pEnvTypeName
, &pEnv
);
192 sal_Bool bNeedsMapping
=
193 (pEnv
|| 0 != rtl_str_compare( pEnvTypeName
, CPPU_CURRENT_LANGUAGE_BINDING_NAME
));
195 OUString
aEnvTypeName( OUString::createFromAscii( pEnvTypeName
) );
200 uno_getEnvironment( &pEnv
, aEnvTypeName
.pData
, 0 );
203 OUString
aCppEnvTypeName( CPPU_CURRENT_LANGUAGE_BINDING_NAME
);
204 uno_getEnvironment( &pCurrentEnv
, aCppEnvTypeName
.pData
, 0 );
206 bNeedsMapping
= (pEnv
!= pCurrentEnv
);
210 OUString
aGetFactoryName( COMPONENT_GETFACTORY
);
211 if (pSym
= osl_getSymbol( lib
, aGetFactoryName
.pData
))
213 OString
aImplName( OUStringToOString( rImplName
, RTL_TEXTENCODING_ASCII_US
) );
217 if (pEnv
&& pCurrentEnv
)
219 Mapping
aCurrent2Env( pCurrentEnv
, pEnv
);
220 Mapping
aEnv2Current( pEnv
, pCurrentEnv
);
222 if (aCurrent2Env
.is() && aEnv2Current
.is())
224 void * pSMgr
= aCurrent2Env
.mapInterface(
225 xSF
.get(), cppu::UnoType
<XMultiServiceFactory
>::get() );
226 void * pKey
= aCurrent2Env
.mapInterface(
227 xKey
.get(), cppu::UnoType
<XRegistryKey
>::get() );
229 void * pSSF
= (*((component_getFactoryFunc
)pSym
))(
230 aImplName
.getStr(), pSMgr
, pKey
);
233 (*pEnv
->pExtEnv
->releaseInterface
)( pEnv
->pExtEnv
, pKey
);
235 (*pEnv
->pExtEnv
->releaseInterface
)( pEnv
->pExtEnv
, pSMgr
);
239 aEnv2Current
.mapInterface(
240 reinterpret_cast< void ** >( &xRet
),
241 pSSF
, cppu::UnoType
<XSingleServiceFactory
>::get() );
242 (*pEnv
->pExtEnv
->releaseInterface
)( pEnv
->pExtEnv
, pSSF
);
249 XSingleServiceFactory
* pRet
= (XSingleServiceFactory
*)
250 (*((component_getFactoryFunc
)pSym
))(
251 aImplName
.getStr(), xSF
.get(), xKey
.get() );
261 (*pEnv
->release
)( pEnv
);
263 (*pCurrentEnv
->release
)( pCurrentEnv
);
266 // ========================= PREVIOUS VERSION =========================
269 OUString
aGetFactoryName( CREATE_COMPONENT_FACTORY_FUNCTION
);
270 if (pSym
= osl_getSymbol( lib
, aGetFactoryName
.pData
))
272 OUString
aCppEnvTypeName( CPPU_CURRENT_LANGUAGE_BINDING_NAME
);
273 OUString
aUnoEnvTypeName( UNO_LB_UNO
);
274 Mapping
aUno2Cpp( aUnoEnvTypeName
, aCppEnvTypeName
);
275 Mapping
aCpp2Uno( aCppEnvTypeName
, aUnoEnvTypeName
);
276 OSL_ENSURE( aUno2Cpp
.is() && aCpp2Uno
.is(), "### cannot get uno mappings!" );
278 if (aUno2Cpp
.is() && aCpp2Uno
.is())
280 uno_Interface
* pUComponentFactory
= 0;
282 uno_Interface
* pUSFactory
= (uno_Interface
*)aCpp2Uno
.mapInterface(
283 xSF
.get(), cppu::UnoType
<XMultiServiceFactory
>::get() );
284 uno_Interface
* pUKey
= (uno_Interface
*)aCpp2Uno
.mapInterface(
285 xKey
.get(), cppu::UnoType
<XRegistryKey
>::get() );
287 pUComponentFactory
= (*((CreateComponentFactoryFunc
)pSym
))(
288 rImplName
.getStr(), pUSFactory
, pUKey
);
291 (*pUKey
->release
)( pUKey
);
293 (*pUSFactory
->release
)( pUSFactory
);
295 if (pUComponentFactory
)
297 XSingleServiceFactory
* pXFactory
=
298 (XSingleServiceFactory
*)aUno2Cpp
.mapInterface(
299 pUComponentFactory
, cppu::UnoType
<XSingleServiceFactory
>::get() );
300 (*pUComponentFactory
->release
)( pUComponentFactory
);
305 pXFactory
->release();
313 osl_unloadModule( lib
);
320 static void createInstance( Reference
< T
> & rxOut
,
321 const Reference
< XMultiServiceFactory
> & xMgr
,
322 const OUString
& rServiceName
)
323 throw (RuntimeException
)
325 Reference
< XInterface
> x( xMgr
->createInstance( rServiceName
), UNO_QUERY
);
329 static sal_Bool s_bSet
= sal_False
;
332 MutexGuard
aGuard( Mutex::getGlobalMutex() );
335 Reference
< XSet
> xSet( xMgr
, UNO_QUERY
);
339 xSet
->insert( makeAny( loadLibComponentFactory(
340 OUString("acceptor"),
341 OUString("com.sun.star.comp.stoc.Acceptor"),
342 xMgr
, Reference
< XRegistryKey
>() ) ) );
344 xSet
->insert( makeAny( loadLibComponentFactory(
345 OUString("connector"),
346 OUString("com.sun.star.comp.stoc.Connector"),
347 xMgr
, Reference
< XRegistryKey
>() ) ) );
349 xSet
->insert( makeAny( loadLibComponentFactory(
350 OUString("remotebridge"),
351 OUString("com.sun.star.bridge.Bridge.various"),
352 xMgr
, Reference
< XRegistryKey
>() ) ) );
354 xSet
->insert( makeAny( loadLibComponentFactory(
355 OUString("brdgfctr"),
356 OUString("com.sun.star.comp.stoc.BridgeFactory"),
357 xMgr
, Reference
< XRegistryKey
>() ) ) );
359 xSet
->insert( makeAny( loadLibComponentFactory(
360 OUString("uuresolver"),
361 OUString("com.sun.star.comp.bridge.UnoUrlResolver"),
362 xMgr
, Reference
< XRegistryKey
>() ) ) );
364 // xSet->insert( makeAny( loadLibComponentFactory(
365 // OUString("javaloader"),
366 // OUString("com.sun.star.comp.stoc.JavaComponentLoader"),
367 // xMgr, Reference< XRegistryKey >() ) ) );
372 x
= xMgr
->createInstance( rServiceName
);
377 throw RuntimeException( "cannot get service instance \"" + rServiceName
);
380 rxOut
= Reference
< T
>::query( x
);
383 throw RuntimeException( "service instance \"" + rServiceName
+
384 "\" does not support demanded interface \"" + cppu::UnoType
<T
>::get().getTypeName() );
389 inline static Sequence
< OUString
> getSupportedServiceNames()
391 return { SERVICENAME
};
395 class TestImpl
: public WeakImplHelper
< XServiceInfo
, XMain
>
397 Reference
< XMultiServiceFactory
> _xSMgr
;
399 Reference
< XInterface
> _xDirect
;
400 Reference
< XInterface
> getDirect() throw (Exception
);
401 Reference
< XInterface
> resolveObject( const OUString
& rUnoUrl
) throw (Exception
);
404 explicit TestImpl( const Reference
< XMultiServiceFactory
> & xSMgr
);
408 virtual OUString SAL_CALL
getImplementationName() throw (RuntimeException
);
409 virtual sal_Bool SAL_CALL
supportsService( const OUString
& rServiceName
) throw (RuntimeException
);
410 virtual Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() throw (RuntimeException
);
413 virtual sal_Int32 SAL_CALL
run( const Sequence
< OUString
> & rArgs
) throw (RuntimeException
);
417 TestImpl::TestImpl( const Reference
< XMultiServiceFactory
> & xSMgr
)
422 TestImpl::~TestImpl()
427 static Reference
< XInterface
> SAL_CALL
TestImpl_create( const Reference
< XMultiServiceFactory
> & xSMgr
)
429 return Reference
< XInterface
>( *new TestImpl( xSMgr
) );
434 OUString
TestImpl::getImplementationName()
435 throw (RuntimeException
)
437 return OUString( IMPLNAME
);
440 sal_Bool
TestImpl::supportsService( const OUString
& rServiceName
)
441 throw (RuntimeException
)
443 return cppu::supportsService(this, rServiceName
);
446 Sequence
< OUString
> TestImpl::getSupportedServiceNames()
447 throw (RuntimeException
)
449 return benchmark_test::getSupportedServiceNames();
453 Reference
< XInterface
> TestImpl::getDirect()
458 MutexGuard
aGuard( Mutex::getGlobalMutex() );
461 Reference
< XSingleServiceFactory
> xFac( loadLibComponentFactory(
463 OUString("com.sun.star.comp.performance.PerformanceTestObject"),
464 _xSMgr
, Reference
< XRegistryKey
>() ) );
466 throw RuntimeException("no test object available!" );
467 _xDirect
= xFac
->createInstance();
473 Reference
< XInterface
> TestImpl::resolveObject( const OUString
& rUnoUrl
)
476 Reference
< XUnoUrlResolver
> xResolver
;
479 OUString("com.sun.star.bridge.UnoUrlResolver") );
481 Reference
< XInterface
> xResolvedObject( xResolver
->resolve( rUnoUrl
) );
483 if (! xResolvedObject
.is())
485 throw RuntimeException( "cannot resolve object \"" + rUnoUrl
+ "\"!" );
488 return xResolvedObject
;
500 TimeEntry( sal_Int64 nLoop_
, sal_uInt32 nTicks_
)
505 inline double secPerCall() const
506 { return (((double)nTicks
) / (nLoop
* 1000)); }
508 double ratio( const TimeEntry
& rEntry
) const;
511 double TimeEntry::ratio( const TimeEntry
& rEntry
) const
513 double f
= rEntry
.nTicks
* nLoop
;
520 return (((double)(nTicks
* rEntry
.nLoop
)) / f
);
525 typedef std::map
< std::string
, TimeEntry
> t_TimeEntryMap
;
530 t_TimeEntryMap _entries
;
531 void insert( const char * pText
, sal_Int64 nLoop
, sal_uInt32 nTicks
);
534 void TimingSheet::insert( const char * pText
, sal_Int64 nLoop
, sal_uInt32 nTicks
)
536 _entries
[ pText
] = TimeEntry( nLoop
, nTicks
);
539 typedef std::unordered_map
< std::string
, TimingSheet
> t_TimingSheetMap
;
541 static void benchmark(
542 TimingSheet
& rSheet
, const Reference
< XInterface
> & xInstance
, sal_Int64 nLoop
)
545 Reference
< XPerformanceTest
> xBench( xInstance
, UNO_QUERY_THROW
);
548 sal_uInt32 tStart
, tEnd
;
550 const Type
& rKnownType
= cppu::UnoType
<XPerformanceTest
>::get();
551 const Type
& rUnKnownType
= cppu::UnoType
<XSet
>::get();
553 ComplexTypes aDummyStruct
;
558 tStart
= getSystemTicks();
561 sal_uInt32 tEndSend
= getSystemTicks();
563 tEnd
= getSystemTicks();
564 rSheet
.insert( "1a: sending simple oneway calls (no params, no return)", nLoop
, tEndSend
- tStart
);
565 rSheet
.insert( "1b: simple oneway calls (no params, no return)", nLoop
, tEnd
- tStart
);
568 tStart
= getSystemTicks();
572 tEnd
= getSystemTicks();
573 rSheet
.insert( "1c: simple synchron calls (no params no return)", nLoop
+1, tEnd
- tStart
);
577 tStart
= getSystemTicks();
580 tEnd
= getSystemTicks();
581 rSheet
.insert( "2a: interface acquire() calls", nLoop
, tEnd
- tStart
);
584 tStart
= getSystemTicks();
587 tEnd
= getSystemTicks();
588 rSheet
.insert( "2b: interface release() calls", nLoop
, tEnd
- tStart
);
590 // queryInterface() for known type
592 tStart
= getSystemTicks();
594 xBench
->queryInterface( rKnownType
);
595 tEnd
= getSystemTicks();
596 rSheet
.insert( "2c: interface query for implemented type", nLoop
, tEnd
- tStart
);
597 // queryInterface() for unknown type
599 tStart
= getSystemTicks();
601 xBench
->queryInterface( rUnKnownType
);
602 tEnd
= getSystemTicks();
603 rSheet
.insert( "2d: interface query for unknown type", nLoop
, tEnd
- tStart
);
605 // create and forget objects
606 Reference
< XPerformanceTest
> xBench2( xBench
);
608 tStart
= getSystemTicks();
610 xBench2
= xBench2
->createObject();
611 tEnd
= getSystemTicks();
612 rSheet
.insert( "3a: create and release test objects", nLoop
, tEnd
- tStart
);
615 Sequence
< Reference
< XInterface
> > aSeq( nLoop
/ 100 );
616 Reference
< XInterface
> * pSeq
= aSeq
.getArray();
618 i
= aSeq
.getLength();
619 tStart
= getSystemTicks();
621 pSeq
[i
] = xBench2
= xBench2
->createObject();
622 tEnd
= getSystemTicks();
623 rSheet
.insert( "3b: create and hold test objects", nLoop
, tEnd
- tStart
);
627 tStart
= getSystemTicks();
629 xBench
->complexIn( aDummyStruct
);
630 tEnd
= getSystemTicks();
631 rSheet
.insert( "4a: complexIn() calls (in struct; return struct)", nLoop
, tEnd
- tStart
);
633 tStart
= getSystemTicks();
635 xBench
->complexInout( aDummyStruct
);
636 tEnd
= getSystemTicks();
637 rSheet
.insert( "4b: complexInout() calls (inout struct; return struct)", nLoop
, tEnd
- tStart
);
640 tStart
= getSystemTicks();
642 xBench
->complexOneway( aDummyStruct
);
643 tEnd
= getSystemTicks();
644 rSheet
.insert( "4c: complexOneway() oneway calls (in struct)", nLoop
, tEnd
- tStart
);
646 tStart
= getSystemTicks();
648 xBench
->complexNoreturn( aDummyStruct
);
649 tEnd
= getSystemTicks();
650 rSheet
.insert( "4d: complexNoreturn() calls (in struct)", nLoop
, tEnd
- tStart
);
652 // attributes, get() methods
654 tStart
= getSystemTicks();
657 tEnd
= getSystemTicks();
658 rSheet
.insert( "5a: getLong() call", nLoop
, tEnd
- tStart
);
660 tStart
= getSystemTicks();
662 xBench
->getLong_attr();
663 tEnd
= getSystemTicks();
664 rSheet
.insert( "5b: get long attribute", nLoop
, tEnd
- tStart
);
667 tStart
= getSystemTicks();
669 xBench
->setLong( 0 );
670 tEnd
= getSystemTicks();
671 rSheet
.insert( "5c: setLong() call", nLoop
, tEnd
- tStart
);
673 tStart
= getSystemTicks();
675 xBench
->setLong_attr( 0 );
676 tEnd
= getSystemTicks();
677 rSheet
.insert( "5d: set long attribute", nLoop
, tEnd
- tStart
);
680 tStart
= getSystemTicks();
683 tEnd
= getSystemTicks();
684 rSheet
.insert( "5e: getHyper() call", nLoop
, tEnd
- tStart
);
686 tStart
= getSystemTicks();
688 xBench
->getHyper_attr();
689 tEnd
= getSystemTicks();
690 rSheet
.insert( "5f: get hyper attribute", nLoop
, tEnd
- tStart
);
693 tStart
= getSystemTicks();
695 xBench
->setHyper( 0 );
696 tEnd
= getSystemTicks();
697 rSheet
.insert( "5g: setHyper() call", nLoop
, tEnd
- tStart
);
699 tStart
= getSystemTicks();
701 xBench
->setHyper_attr( 0 );
702 tEnd
= getSystemTicks();
703 rSheet
.insert( "5h: set hyper attribute", nLoop
, tEnd
- tStart
);
706 tStart
= getSystemTicks();
709 tEnd
= getSystemTicks();
710 rSheet
.insert( "5i: getFloat() call", nLoop
, tEnd
- tStart
);
712 tStart
= getSystemTicks();
714 xBench
->getFloat_attr();
715 tEnd
= getSystemTicks();
716 rSheet
.insert( "5j: get float attribute",nLoop
, tEnd
- tStart
);
719 tStart
= getSystemTicks();
721 xBench
->setFloat( 0.0 );
722 tEnd
= getSystemTicks();
723 rSheet
.insert( "5k: setFloat() call", nLoop
, tEnd
- tStart
);
725 tStart
= getSystemTicks();
727 xBench
->setFloat_attr( 0.0 );
728 tEnd
= getSystemTicks();
729 rSheet
.insert( "5l: set float attribute", nLoop
, tEnd
- tStart
);
732 tStart
= getSystemTicks();
735 tEnd
= getSystemTicks();
736 rSheet
.insert( "5m: getDouble() call", nLoop
, tEnd
- tStart
);
738 tStart
= getSystemTicks();
740 xBench
->getDouble_attr();
741 tEnd
= getSystemTicks();
742 rSheet
.insert( "5n: get double attribute", nLoop
, tEnd
- tStart
);
744 tStart
= getSystemTicks();
746 xBench
->setDouble( 0.0 );
747 tEnd
= getSystemTicks();
748 rSheet
.insert( "5o: setDouble() call", nLoop
, tEnd
- tStart
);
750 tStart
= getSystemTicks();
752 xBench
->setDouble_attr( 0.0 );
753 tEnd
= getSystemTicks();
754 rSheet
.insert( "5p: set double attribute", nLoop
, tEnd
- tStart
);
757 tStart
= getSystemTicks();
760 tEnd
= getSystemTicks();
761 rSheet
.insert( "6a: getString() call (empty)", nLoop
, tEnd
- tStart
);
763 tStart
= getSystemTicks();
765 xBench
->getString_attr();
766 tEnd
= getSystemTicks();
767 rSheet
.insert( "6b: get empty string attribute", nLoop
, tEnd
- tStart
);
770 OUString aDummyString
;
771 tStart
= getSystemTicks();
773 xBench
->setString( aDummyString
);
774 tEnd
= getSystemTicks();
775 rSheet
.insert( "6c: setString() call (empty)", nLoop
, tEnd
- tStart
);
777 tStart
= getSystemTicks();
779 xBench
->setString_attr( aDummyString
);
780 tEnd
= getSystemTicks();
781 rSheet
.insert( "6d: set empty string attribute", nLoop
, tEnd
- tStart
);
784 tStart
= getSystemTicks();
786 xBench
->getInterface();
787 tEnd
= getSystemTicks();
788 rSheet
.insert( "7a: getInterface() call (null)", nLoop
, tEnd
- tStart
);
790 tStart
= getSystemTicks();
792 xBench
->getInterface_attr();
793 tEnd
= getSystemTicks();
794 rSheet
.insert( "7b: get interface attribute", nLoop
, tEnd
- tStart
);
797 Reference
< XInterface
> aDummyInterface
;
798 tStart
= getSystemTicks();
800 xBench
->setInterface( aDummyInterface
);
801 tEnd
= getSystemTicks();
802 rSheet
.insert( "7c: setInterface() call (null)", nLoop
, tEnd
- tStart
);
804 tStart
= getSystemTicks();
806 xBench
->setInterface_attr( Reference
< XInterface
>() );
807 tEnd
= getSystemTicks();
808 rSheet
.insert( "7d: set interface attribute", nLoop
, tEnd
- tStart
);
811 tStart
= getSystemTicks();
814 tEnd
= getSystemTicks();
815 rSheet
.insert( "8a: getAny() call (empty)", nLoop
, tEnd
- tStart
);
817 tStart
= getSystemTicks();
819 xBench
->getAny_attr();
820 tEnd
= getSystemTicks();
821 rSheet
.insert( "8b: get empty any attribute", nLoop
, tEnd
- tStart
);
825 tStart
= getSystemTicks();
827 xBench
->setAny( aDummyAny
);
828 tEnd
= getSystemTicks();
829 rSheet
.insert( "8c: setAny() call (empty)", nLoop
, tEnd
- tStart
);
831 tStart
= getSystemTicks();
833 xBench
->setAny_attr( aDummyAny
);
834 tEnd
= getSystemTicks();
835 rSheet
.insert( "8d: set empty any attribute", nLoop
, tEnd
- tStart
);
838 tStart
= getSystemTicks();
840 xBench
->getSequence();
841 tEnd
= getSystemTicks();
842 rSheet
.insert( "9a: getSequence() call (empty)", nLoop
, tEnd
- tStart
);
844 tStart
= getSystemTicks();
846 xBench
->getSequence_attr();
847 tEnd
= getSystemTicks();
848 rSheet
.insert( "9b: get empty sequence attribute", nLoop
, tEnd
- tStart
);
850 Sequence
< Reference
< XInterface
> > aDummySeq
;
851 tStart
= getSystemTicks();
853 xBench
->setSequence( aDummySeq
);
854 tEnd
= getSystemTicks();
855 rSheet
.insert( "9c: setSequence() call (empty)", nLoop
, tEnd
- tStart
);
857 tStart
= getSystemTicks();
859 xBench
->setSequence_attr( aDummySeq
);
860 tEnd
= getSystemTicks();
861 rSheet
.insert( "9d: set empty sequence attribute", nLoop
, tEnd
- tStart
);
864 tStart
= getSystemTicks();
867 tEnd
= getSystemTicks();
868 rSheet
.insert( "Aa: getStruct() call", nLoop
, tEnd
- tStart
);
870 tStart
= getSystemTicks();
872 xBench
->getStruct_attr();
873 tEnd
= getSystemTicks();
874 rSheet
.insert( "Ab: get struct attribute", nLoop
, tEnd
- tStart
);
877 tStart
= getSystemTicks();
879 xBench
->setStruct( aDummyStruct
);
880 tEnd
= getSystemTicks();
881 rSheet
.insert( "Ac: setStruct() call", nLoop
, tEnd
- tStart
);
883 tStart
= getSystemTicks();
885 xBench
->setStruct_attr( aDummyStruct
);
886 tEnd
= getSystemTicks();
887 rSheet
.insert( "Ad: set struct attribute", nLoop
, tEnd
- tStart
);
891 // tStart = getSystemTicks();
893 // xBench->setSequence( aSeq );
894 // tEnd = getSystemTicks();
895 // rSheet.insert( "transfer of existing objects", nLoop, tEnd - tStart );
899 tStart
= getSystemTicks();
904 xBench
->raiseRuntimeException();
906 catch (RuntimeException
&)
910 tEnd
= getSystemTicks();
911 rSheet
.insert( "Ba: raising RuntimeException", nLoop
, tEnd
- tStart
);
917 static OUString
extractParam( const Sequence
< OUString
> & rArgs
, const OUString
& rParam
)
919 const OUString
* pArgs
= rArgs
.getConstArray();
920 for ( sal_Int32 nPos
= rArgs
.getLength(); nPos
--; )
922 if (pArgs
[nPos
].startsWith( rParam
) &&
923 pArgs
[nPos
].getLength() > (rParam
.getLength()+1))
925 return pArgs
[nPos
].copy( rParam
.getLength() +1 ); // XXX=bla
931 const sal_Int32 nMagicNumberDirect
= 34000;
935 sal_Int32
TestImpl::run( const Sequence
< OUString
> & rArgs
)
936 throw (RuntimeException
)
939 FILE * stream
= stderr
;
940 sal_Int64 nLoop
= NLOOP
;
941 OUString
aArg("dms");
945 OUString
aLoopStr( extractParam( rArgs
, OUString("loop") ) );
946 if (aLoopStr
.getLength())
948 sal_Int64 n
= aLoopStr
.toInt64();
953 OUString
aDurationStr( extractParam( rArgs
, OUString("duration" ) ) );
954 if( aDurationStr
.getLength() )
956 sal_Int64 n
= aDurationStr
.toInt64();
958 nLoop
= nMagicNumberDirect
* n
;
961 OUString
aLogStr( extractParam( rArgs
, OUString("log") ) );
962 if (aLogStr
.getLength())
964 if (aLogStr
.equalsAscii( "stderr" ) )
968 else if (aLogStr
.equalsAscii( "stdout" ) )
974 OString
aFileName( OUStringToOString( aLogStr
, RTL_TEXTENCODING_ASCII_US
) );
975 stream
= ::fopen( aFileName
.getStr(), "w" );
978 throw RuntimeException( "cannot open file for writing: \"" + aLogStr
+ "\"!" );
983 OUString
aArgStr( extractParam( rArgs
, OUString("opt") ) );
984 if (aArgStr
.getLength())
989 if (! rArgs
.getLength())
990 out( "\n> no options given, using defaults" );
996 if (stream
== stderr
)
998 else if (stream
== stdout
)
999 out( "stdout loop=" );
1005 t_TimingSheetMap aSheets
;
1006 TimingSheet aDirect
;
1009 if (aArg
.indexOf( 'd' ) >= 0)
1011 // in process direct test
1012 sal_uInt32 nStart
= getSystemTicks();
1013 benchmark( aDirect
, getDirect(), nLoop
);
1014 sal_uInt32 nEnd
= getSystemTicks();
1015 fprintf( stderr
, "Duration (direct in process): %g s\n", (nEnd
- nStart
)/1000. );
1019 if (aArg
.indexOf( 'm' ) >= 0)
1021 // in process uno dispatch
1022 Environment aCppEnv
, aAnoCppEnv
;
1023 OUString
aCurrentLanguageBindingName( CPPU_CURRENT_LANGUAGE_BINDING_NAME
);
1024 uno_getEnvironment( reinterpret_cast< uno_Environment
** >( &aCppEnv
),
1025 aCurrentLanguageBindingName
.pData
, 0 );
1027 uno_createEnvironment( reinterpret_cast< uno_Environment
** >( &aAnoCppEnv
),
1028 aCurrentLanguageBindingName
.pData
, 0 );
1030 // pseudo mapping uno<->uno: does nothing!
1031 Mapping
aMapping( aCppEnv
.get(), aAnoCppEnv
.get(), OUString("pseudo") );
1032 if (! aMapping
.is())
1033 throw RuntimeException("no pseudo mapping available!" );
1035 Reference
< XInterface
> xMapped
;
1036 Reference
< XInterface
> xDirect( getDirect() );
1037 aMapping
.mapInterface( reinterpret_cast< void ** >( &xMapped
), xDirect
.get(),
1038 cppu::UnoType
<decltype(xDirect
)>::get() );
1040 throw RuntimeException("mapping object failed!" );
1042 sal_uInt32 nStart
= getSystemTicks();
1043 benchmark( aSheets
[ "mapped in process" ], xMapped
, nLoop
/ 100 );
1044 sal_uInt32 nEnd
= getSystemTicks();
1045 fprintf( stderr
, "Duration (mapped in process): %g s\n", (nStart
- nEnd
)/1000. );
1049 if (aArg
.indexOf( 's' ) >= 0)
1051 // start server process
1052 oslSecurity hSecurity
= osl_getCurrentSecurity();
1054 throw RuntimeException("cannot get current security handle!" );
1056 OUString aArgs
[] = {
1058 OUString("com.sun.star.comp.performance.PerformanceTestObject"),
1061 OUString("libperfobj.so"),
1063 OUString("perfobj.dll"),
1066 OUString("applicat.rdb"),
1068 OUString("uno:socket,host=localhost,port=6000;iiop;TestRemoteObject"),
1069 OUString("--singleaccept")
1071 rtl_uString
* pArgs
[] = {
1083 out( "\n> executing: \"uno" );
1084 for ( sal_Int32 nPos
= 0; nPos
< (sizeof(aArgs
) / sizeof(OUString
)); ++nPos
)
1091 oslProcess hProcess
= 0;
1092 OUString
aUnoExe("uno");
1093 OUString
aWorkingDir(".");
1095 aUnoExe
.pData
, pArgs
, sizeof(aArgs
) / sizeof(OUString
),
1096 osl_Process_SEARCHPATH
| osl_Process_DETACHED
| osl_Process_NORMAL
,
1097 hSecurity
, aWorkingDir
.pData
, 0, 0, &hProcess
);
1099 osl_freeSecurityHandle( hSecurity
);
1101 throw RuntimeException("cannot start server process!" );
1102 osl_freeProcessHandle( hProcess
);
1104 // wait three seconds
1105 osl::Thread::wait(std::chrono::seconds(3));
1107 // connect and resolve outer process object
1108 Reference
< XInterface
> xResolvedObject( resolveObject( OUString("uno:socket,host=localhost,port=6000;iiop;TestRemoteObject") ) );
1110 benchmark( aSheets
[ "remote same host" ], xResolvedObject
, nLoop
/ 300 );
1114 if (aArg
.indexOf( 'r' ) >= 0)
1117 OUString
aUnoUrl( extractParam( rArgs
, OUString("url") ) );
1118 if (! aUnoUrl
.getLength())
1119 throw RuntimeException( "performance test r(emote) needs additional uno url!" );
1121 // connect and resolve outer process object
1122 Reference
< XInterface
> xResolvedObject( resolveObject( aUnoUrl
) );
1124 sal_Int32 t1
= getSystemTicks();
1125 OString o
= OUStringToOString( aUnoUrl
, RTL_TEXTENCODING_ASCII_US
);
1126 benchmark( aSheets
[ o
.getStr() ], xResolvedObject
, nLoop
/ 900 );
1127 sal_Int32 t2
= getSystemTicks();
1128 fprintf( stderr
, "Duration (%s): %g s\n", o
.getStr(),(t2
- t1
)/1000. );
1132 if (aArg
.indexOf( 'j' ) >= 0)
1135 benchmark( aSheets
[ "java in process" ],
1136 _xSMgr
->createInstance("com.sun.star.comp.benchmark.JavaTestObject"),
1143 out( "\nTimes( ratio to direct in process )", stream
);
1146 sal_Int32 nPos
= 60;
1147 out( "[direct in process]", stream
, nPos
);
1148 for ( const auto& rSheet
: aSheets
)
1151 out( "[", stream
, nPos
);
1152 out( rSheet
.first
.c_str(), stream
);
1155 for ( const auto& rTopics
: aDirect
._entries
)
1157 const std::string
& rTopic
= rTopics
.first
;
1159 out( "\n", stream
);
1160 out( rTopic
.c_str(), stream
);
1162 out( ":", stream
, 58, '.' );
1164 sal_Int32 nPos
= 60;
1166 double secs
= rTopics
.second
.secPerCall();
1169 out( secs
* 1000, stream
, nPos
);
1170 out( "ms", stream
);
1174 out( "NA", stream
, nPos
);
1177 for ( const auto& rSheet
: aSheets
)
1179 const t_TimeEntryMap::const_iterator
iFind( rSheet
.second
._entries
.find( rTopic
) );
1180 OSL_ENSURE( iFind
!= rSheet
.second
._entries
.end(), "####" );
1184 double secs
= (*iFind
).second
.secPerCall();
1187 out( secs
* 1000, stream
, nPos
);
1188 out( "ms", stream
);
1190 out( " (", stream
);
1191 double ratio
= (*iFind
).second
.ratio( rTopics
.second
);
1194 out( ratio
, stream
);
1195 out( " x)", stream
);
1199 out( "NA)", stream
);
1204 out( "NA", stream
, nPos
);
1209 catch (Exception
& rExc
)
1211 if (stream
!= stderr
&& stream
!= stdout
)
1213 throw RuntimeException( rExc
.Message
, rExc
.Context
);
1216 if (stream
!= stderr
&& stream
!= stdout
)
1219 out( "\n> done.\n" );
1229 sal_Bool SAL_CALL
component_writeInfo(
1230 void * pServiceManager
, void * pRegistryKey
)
1236 Reference
< XRegistryKey
> xNewKey(
1237 reinterpret_cast< XRegistryKey
* >( pRegistryKey
)->createKey(
1238 OUString( "/" IMPLNAME
"/UNO/SERVICES" ) ) );
1239 xNewKey
->createKey( OUString( SERVICENAME
) );
1243 catch (InvalidRegistryException
&)
1245 OSL_FAIL( "### InvalidRegistryException!" );
1251 SAL_DLLPUBLIC_EXPORT
void * SAL_CALL
component_getFactory(
1252 const char * pImplName
, void * pServiceManager
, void * pRegistryKey
)
1256 if (pServiceManager
&& rtl_str_compare( pImplName
, IMPLNAME
) == 0)
1258 Reference
< XSingleServiceFactory
> xFactory( createSingleFactory(
1259 reinterpret_cast< XMultiServiceFactory
* >( pServiceManager
),
1260 OUString( IMPLNAME
),
1261 benchmark_test::TestImpl_create
,
1262 benchmark_test::getSupportedServiceNames() ) );
1266 xFactory
->acquire();
1267 pRet
= xFactory
.get();
1275 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */