? i18npool/i18npool.vpj
Index: i18npool/inc/transliterationImpl.hxx
===================================================================
RCS file: /cvs/l10n/i18npool/inc/transliterationImpl.hxx,v
retrieving revision 1.6
diff -u -r1.6 transliterationImpl.hxx
--- i18npool/inc/transliterationImpl.hxx	7 Sep 2005 16:57:28 -0000	1.6
+++ i18npool/inc/transliterationImpl.hxx	23 Aug 2007 20:24:58 -0000
@@ -133,12 +133,25 @@
     com::sun::star::uno::Reference< XLocaleData > localedata;
     com::sun::star::uno::Reference< com::sun::star::i18n::XExtendedTransliteration > caseignore;
 
+    /** structure to cache the last transliteration body used. */
+    struct TransBody
+    {
+        ::osl::Mutex mutex;
+        ::rtl::OUString Name;
+        ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XExtendedTransliteration > Body;
+    };
+    static TransBody lastTransBody;
+
     virtual sal_Bool SAL_CALL loadModuleByName( const rtl::OUString& implName, 
         com::sun::star::uno::Reference<com::sun::star::i18n::XExtendedTransliteration> & body, const com::sun::star::lang::Locale& rLocale) 
         throw(com::sun::star::uno::RuntimeException);
 
     void clear();
 
+    void loadBody( ::rtl::OUString &implName, 
+        ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XExtendedTransliteration >& body )
+        throw (::com::sun::star::uno::RuntimeException);
+
     com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getRange(
         const com::sun::star::uno::Sequence< rtl::OUString > &inStrs,
         sal_Int32 length, const sal_Int16 _nCascade)
Index: i18npool/source/transliteration/transliterationImpl.cxx
===================================================================
RCS file: /cvs/l10n/i18npool/source/transliteration/transliterationImpl.cxx,v
retrieving revision 1.15
diff -u -r1.15 transliterationImpl.cxx
--- i18npool/source/transliteration/transliterationImpl.cxx	17 Sep 2006 09:31:51 -0000	1.15
+++ i18npool/source/transliteration/transliterationImpl.cxx	23 Aug 2007 20:24:58 -0000
@@ -154,6 +154,8 @@
   {(TransliterationModules)0, (TransliterationModulesNew)0,  NULL}
 };
 
+TransliterationImpl::TransBody TransliterationImpl::lastTransBody;
+
 // Constructor/Destructor
 TransliterationImpl::TransliterationImpl(const Reference <XMultiServiceFactory>& xMSF) : xSMgr(xMSF)
 {
@@ -596,9 +598,18 @@
     caseignoreOnly = sal_True;
 }
 
-static void SAL_CALL loadBody( Reference<XMultiServiceFactory>& xSMgr, OUString &implName, 
-                        Reference<XExtendedTransliteration>& body) throw(RuntimeException)
+void TransliterationImpl::loadBody( OUString &implName, Reference<XExtendedTransliteration>& body ) 
+    throw (RuntimeException)
 {
+    ::osl::MutexGuard guard(lastTransBody.mutex);
+
+    if (implName.equals(lastTransBody.Name))
+    {
+        // Use the cached body instead of going through the expensive looping again.
+        body = lastTransBody.Body;
+        return;
+    }
+
     Reference< XContentEnumerationAccess > xEnumAccess( xSMgr, UNO_QUERY );
     Reference< XEnumeration > xEnum(xEnumAccess->createContentEnumeration(
                                     OUString::createFromAscii(TRLT_SERVICELNAME_L10N)));
@@ -615,6 +626,8 @@
                             a = xI->queryInterface(::getCppuType((
                                         const Reference<XExtendedTransliteration>*)0));
                             a >>= body;
+                            lastTransBody.Name = implName;
+                            lastTransBody.Body = body;
                             return;
                         }
                     }
@@ -630,7 +643,7 @@
         Reference<XExtendedTransliteration>& body, const Locale& rLocale) throw(RuntimeException)
 {
     OUString cname = OUString::createFromAscii(TRLT_IMPLNAME_PREFIX) + implName;
-    loadBody(xSMgr, cname, body);
+    loadBody(cname, body);
     if (body.is()) {
         body->loadModule((TransliterationModules)0, rLocale); // toUpper/toLoad need rLocale
 
@@ -642,7 +655,7 @@
                 if (! caseignore.is()) {
                     OUString bname = OUString::createFromAscii(TRLT_IMPLNAME_PREFIX) +
                                 OUString::createFromAscii(TMlist[0].implName);
-                    loadBody(xSMgr, bname, caseignore);
+                    loadBody(bname, caseignore);
                 }
                 if (caseignore.is())
                     caseignore->loadModule(TMlist[i].tm, rLocale);
