Performance/Ideas/Easy UNO Services Merging

From Apache OpenOffice Wiki
Jump to: navigation, search

Loading many small libraries results in performance penalties, compared to loading fewer large libraries, so people suggested to combine some of the UNO services libraries.

The problem here is that all libraries export functions with the same names

 component_getImplementationEnvironment
 component_writeInfo
 component_getFactory

So merging libraries means you also need to combine these functions - every time you want to organize the services differently.

For making it easier, it could be a good idea to make all these function names unique for each service:

 component_getImplementationEnvironment_<current_library_name>
 component_writeInfo_<current_library_name>
 component_getFactory_<current_library_name>

A new tool could then create a stub for each UNO service library:

 unostub <name1> [<name2>, ...]

For getting the current behavior, with all the single service libraries, you would add something to the makefile like

 unostub <current_library_name>

which would result in something like

 component_getImplementationEnvironment(...)
 {
   component_getImplementationEnvironment_<current_library_name>(...) 
 }
 component_writeInfo(...)
 {
   component_writeInfo_<current_library_name>(...) 
 }
 component_getFactory(...)
 {
   return component_getFactory_<current_library_name> (...)
 }

So in the end you will have exactly the same like before, only one indirection more.

The benefit starts when you try to combine certain services, which you probably do based on some logic (what belongs together), or some experiments (what is needed in startup svdem,startcenter/writer/...).

 unostub <current_library_name_1> <current_library_name_2> ... <current_library_name_n>
 component_getImplementationEnvironment ( const sal_Char** ppEnvTypeName, ... )
 {
   *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
     // assuming all component_getImplementationEnvironment_<current_library_name_N> do just that, too
 }
 component_writeInfo(...)
 {
   return component_writeInfo_<current_library_name_1>(...)
     && component_writeInfo_<current_library_name_2>(...)
     ...
     && component_writeInfo_<current_library_name_n>(...);
 }
 component_getFactory(...)
 {
   void* pRet = component_getFactory_<current_library_name_1>(...) 
   if ( !*pRet )
     pRet = component_getFactory_<current_library_name_2>(...) 
   ...
   if ( !*pRet )
     pRet = component_getFactory_<current_library_name_n>(...) 
   return pRet;
 }

This way, we could very easily combine different services, or easily change anything later again.

In the different UNO services implementations, you must make sure that

 a) Don't have an unconditional "else" clause assuming it can only be the last service you didn't check for with some "if" before
 b) Don't use assertions if you receive a service name you don't expect

TBD...

Personal tools