Thanks for the help. I have done the following as per your 3 suggestions, but
have noticed no increase in speed. Any other ideas, or can you point out
something I am doing wrong?
1) I already had my compiler set to build for release and optimize for speed.
2) I have now implemented a callback class, but still need the output as a
string to pass back to java, so I am still wrapping a stringstream in the
callback class - is this still bad for memory allocation? If so, what stream
do I use as I don't want IO to file (unless I have to), and I don't know how to
get a string from the other streams. I have changed my transform method to use
a compiled stylesheet and a XalanDefaultParsedSource. Here is the code for my
callback handler:
#if defined(XALAN_CLASSIC_IOSTREAMS)
#include <sstream.h>
#else
#include <sstream>
#endif
class StringCallbackHandler
{
public:
StringCallbackHandler(std::stringstream* thestream) :
xmlStream(thestream)
{
assert(xmlStream != 0);
}
CallbackSizeType write(const char* theData, CallbackSizeType theLength)
{
xmlStream->write(theData, theLength);
return theLength;
}
void flush() {
xmlStream->flush();
}
private:
std::stringstream* xmlStream;
};
// 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
writeCallback(
const char* theData,
CallbackSizeType theLength,
void* theHandle)
{
#if defined(XALAN_OLD_STYLE_CASTS)
return ((StringCallbackHandler*)theHandle)->write(theData, theLength);
#else
return
reinterpret_cast<StringCallbackHandler*>(theHandle)->write(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
flushCallback(void* theHandle)
{
#if defined(XALAN_OLD_STYLE_CASTS)
((StringCallbackHandler*)theHandle)->flush();
#else
reinterpret_cast<StringCallbackHandler*>(theHandle)->flush();
#endif
}
}
and some code from my transform method:
stringstream theOutXMLStream;
// CallbackHandler writes incrementally, saving on memory
allocation
StringCallbackHandler theHandler(&theOutXMLStream);
// XalanParsedSource required to use callback on compiled
stylesheet
XSLTInputSource * theInputSource;
// Do the transform.
time_t currenttime = time(NULL);
printf( "Prepping Input %ld\n", currenttime );
ifstream testfile(input);
if ( testfile.is_open() ) {
// input is filepath
testfile.close();
theInputSource = new XSLTInputSource(input);
currenttime = time(NULL);
printf( "Start Transforming File %ld\n", currenttime );
} else {
// input was actual xml string
istrstream theInXMLStream(input, strlen(input));
theInputSource = new XSLTInputSource(theInXMLStream);
currenttime = time(NULL);
printf( "Start Transforming String %ld\n", currenttime
);
}
XalanDefaultParsedSource theParsedSource(*theInputSource);
//result = theXalanTransformer.transform(theInputSource,
stylesheetSource, theOutXMLStream);
//result = theXalanTransformer->transform(theInputSource,
theCompiledStylesheet, theOutXMLStream);
result = theXalanTransformer->transform(
theParsedSource,
theCompiledStylesheet,
&theHandler,
writeCallback,
flushCallback);
currenttime = time(NULL);
printf( "End Transforming %ld\n", currenttime );
3) How does one test a DLL independently? Are you suggesting I compile as an
executable with a main method and test, and just assume the DLL will perform
similarly? My transform method prints out the system time very very often, so
I know the JNI interface isn't the slow part, just the
XalanTransformer::transform method call.
Thanks again.
Brian
-----Original Message-----
From: David Bertoni [mailto:[EMAIL PROTECTED]
Sent: Friday, October 07, 2005 12:29 PM
To: [email protected]
Subject: Re: Slow performance of XalanTransformer.transform in DLL
Brian Frutchey wrote:
> I am writing a JNI bridge which uses Xalan-C++ to speed up the XSLT
> processing in a Java application. Everything is functional, but the
> XalanTransformer.transform method is perform exceptionally slow (slower
> than a native Java implementation using Xalan-J). Strangely, I am
> copying the code from the XalanTransformer sample project, but when I
> use the packaged executable from the command line on the same file and
> stylesheet the performance is lightning fast.
Do you mean the XalanTransformer sample application, or the Xalan
executable?
> The only major difference between my code and the sample project is
> that instead of compiling as an executable I am compiling as a DLL.
> Could this be the source of my performance hit? My DLL will convert a
> 1MB file in 44secs, the executable takes about .2secs. What else
> might it be?
>
Are you testing this outside of the Java environment, to make sure
nothing in Java is taking up the time? Building into a DLL should not
have any effect on performance.
> Code:
>
...
> XALAN_USING_STD(istrstream)
> XALAN_USING_STD(ostringstream)
Using std::ostringstream or std::ostrstream is never a good idea if you
want the best performance. Take a look at the XalanTransformerCallback
sample to see how you can use the callback mechanism to avoid multiple
memory allocations and extra copies of the serialized result.
If you're having performance problems, I suggest you do the following:
1. Make sure you are building a release DLL and the compiler is set to
optimize.
2. Use a callback to avoid extraneous memory allocations and extra
copies of the data.
3. Test your code without any JNI artifacts, to verify the performance
problem is actually related to Xalan and your code that works with
Xalan, and not JNI.
>
> This email message and any attachments are confidential to Endeca. If
> you are not the intended recipient, please notify Endeca immediately --
> by replying to this message or by sending an email to: [EMAIL PROTECTED]
> -- and destroy all copies of this message and any attachments. Thank you.
>
You should remove this tag from your postings to public mailing lists,
since your message is _not_ confidential in the least.
Dave