Hello, 

To reproduce this problem I think you will need my XSL and XML files.  But I 
don't want to
overload the mail list... (I already sent a massive message to the subscibe 
address - sorry about
this but I don't use mailing lists much).

The main app I have is a fairly memory hungry GUI, so I tried running the Xalan 
transform in its
own process,
this helped a bit.  
The performance in RELEASE is about 2 minutes.
The performance in DEBUG is about 30 mins.
This is similar to the performance of the Xalan sample 
'XalanCallbackTransformer' (RELEASE 2
minutes, DEBUG 11 minutes).

> Are you by any chance using a ostrstream or ostringstream instance as to
> hold the result of the transformation?

I am using a callback handler, and it uses a vector of string objects on the 
heap.
I don't think this is related to the problem - nearly all the time is spent 
processing BEFORE
there is more than 1KB of output.


> You cannot build Xalan-C without Xerces-C, and I'm not sure why you 

I got the idea from the Apache page:
http://xml.apache.org/xalan-c/usagepatterns.html#xercesdomwrapperparsedsource

"Performance is much better when Xalan-C++ uses native source tree handling 
rather than
interacting with the Xerces DOMParser".   
What does this mean then, if Xalan cannot be built without Xerces ?

> any performance issues, so why do you think Xerces-C is the problem in 
> your code?
> 
> Please show us some code that shows us how you are invoking Xalan-C.  In 
> particular, show us how you are handling the output of the transformation.
> 

I believe the problem is with Xalan-C not Xerces-C, since even the sample
'XalanCallbackTransformer' takes 2 minutes in RELEASE build.
Here is my code in any case:


Thanks,

Sean

=============



...
//Initialise Xalan 
...

        XALAN_USING_STD(cerr)
        XALAN_USING_STD(cout)
        XALAN_USING_STD(endl)

        //Initialise the Xalan transformer:
        XALAN_USING_XERCES(XMLPlatformUtils)
        
        XALAN_USING_XALAN(XalanTransformer)
        
        // Call the static initializer for Xerces.
        XMLPlatformUtils::Initialize();
        
        // Initialize Xalan.
        XalanTransformer::initialize();
        
        // Create a XalanTransformer.
        pXalanTransformer = new XalanTransformer;

...

//invoke the transform:

...

BOOL CMXmlTransformer::TransformParsedXMLWithXSLFile(CString _csXSLFilepath, 
CString
_csXMLFilepathOut, BOOL* _pbErrors)
{
        //Perform an XSL transform on a compiled XML file, using a compiled XSL.

        ...

        long lRetVal = pXalanTransformer->parseSource(X(_csXMLFilepath), 
pXalanParsedXML);

        ...

        if(pXalanParsedXML==NULL)
        {
                ASSERT(FALSE);
                ...
                return FALSE; //cannot continue
        }
        
        BOOL bSuccess = FALSE;
        (*_pbErrors) = FALSE;
        try
        {
                XalanCompiledStylesheet* pCompiledStylesheet = NULL;
                long lRetVal = 
pXalanTransformer->compileStylesheet(X(_csXSLFilepath), pCompiledStylesheet);
                if(lRetVal!=0)
                {
                        ASSERT(FALSE);
                        ...
                }
                
                // CallbackHandler writes incrementally, saving on memory 
allocation and so improving
performance
                CMXalanCallbackHandler xalanHandler(pClient);

                // Do the transform.
                long lResult = pXalanTransformer->transform(
                        *pXalanParsedXML, 
                        pCompiledStylesheet, 
                        &xalanHandler,
                        XalanWriteCallback,
                        XalanFlushCallback
                );
                if(lResult!=0)
                {
                        ASSERT(FALSE);
                        ...
                }

                {
                        //In any case, now write out the XML to a file (even if 
empty):
                        vector< CString* >* pVecStrings = 
xalanHandler.GetXMLStrings();
                        CFile fileXML; //destructor of CFile will call Close()

                        ...
                }
        }
        catch(...)
        {
                ASSERT(FALSE);
                ...
        }

        ...

        return bSuccess;
}

//Xalan callback handler:


//////////////////////////////////////////////////////////////////////////////
//begin class CMXalanCallbackHandler

//public:
CMXalanCallbackHandler::CMXalanCallbackHandler(IXmlTransformerClient* _pClient)
{
        pClient = _pClient;
        Reset();
}

/*virtual*/ CMXalanCallbackHandler::~CMXalanCallbackHandler()
{
        Clear();
}

void CMXalanCallbackHandler::Clear()
{
        for(vector< CString* >::iterator it = vecString.begin(); it != 
vecString.end(); it++)
        {
                delete *it;
        }
        vecString.clear();
}

vector< CString* >* CMXalanCallbackHandler::GetXMLStrings()
{
        return &vecString;
}

inline void CMXalanCallbackHandler::AllocateSpace()
{
        if(vecString.size() == vecString.capacity())
        {
                //allocate another block of vector entries:
                vecString.reserve( vecString.size() + 
XML_VECTOR_NUMBER_OF_CHUNKS );
        }
}

void CMXalanCallbackHandler::Reset()
{
        Clear();
        //pre-allocate some space in the vector:
        vecString.reserve(XML_VECTOR_NUMBER_OF_CHUNKS); //i.e. reserve room for 
500 chunks of XML data
}

CallbackSizeType CMXalanCallbackHandler::WriteChunk(const char* _pszData, 
CallbackSizeType
_length)
{
        TRACE1(_T("\nCMXalanCallbackHandler::WriteChunk(%ld)\n"), _length);
        AllocateSpace();
        
        CString* pXMLChunk = new CString(_pszData, _length);
        vecString.push_back(pXMLChunk); //use new CString to prevent extra 
copying

#ifdef _XMLMODEL_DIAGNOSTICS //for DEBUGing code only
        //need to NULL-terminate the string in order to output it:
        CString csTempOut(pszBuffer, _length);
        csTempOut += _T("\0");
TRACE( csTempOut.Left(500) ); //TRACE() can handle 512 chars max
TRACE( csTempOut.Mid(500) ); //TRACE() can handle 512 chars max
#endif //_XMLMODEL_DIAGNOSTICS

        if(pClient)
        {
                pClient->ChunkAdded();
        }

        return _length;
}

void CMXalanCallbackHandler::Flush()
{
        //not a stream, so do nothing
}

// These functions need to have C linkage, so surround them with an extern C 
block... 
extern "C" 
{
        // This is the write callback function, which casts the handle
        // to the appropriate type, then calls the write() member function
        // on the CallbackHandler class.
        CallbackSizeType XalanWriteCallback(
                const char* theData,
                CallbackSizeType theLength,
                void* theHandle)
        { 
#if defined(XALAN_OLD_STYLE_CASTS) 
                return 
((CMXalanCallbackHandler*)theHandle)->WriteChunk(theData, theLength); 
#else 
                return 
reinterpret_cast<CMXalanCallbackHandler*>(theHandle)->WriteChunk(theData, 
theLength);
#endif 
        } 
        
        // This is the flush callback function, which casts the handle 
        // to the appropriate type, then calls the flush() member function 
        // on the CallbackHandler class. 
        void XalanFlushCallback(void* theHandle) 
        { 
#if defined(XALAN_OLD_STYLE_CASTS) 
                ((CMXalanCallbackHandler*)theHandle)->Flush();
#else 
                reinterpret_cast<CMXalanCallbackHandler*>(theHandle)->Flush();
#endif
        }

} //extern

//end of class CMXalanCallbackHandler
//////////////////////////////////////////////////////////////////////////////

=============


___________
Sean Ryan


___________
Sean Ryan

Reply via email to