activemq-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Gerald Kaas (JIRA)" <>
Subject [jira] Commented: (AMQCPP-93) Performance analysis
Date Fri, 22 Jun 2007 18:38:34 GMT


Gerald Kaas commented on AMQCPP-93:

I've been spending the last day or so using a profiler against a test harness we have which
sends and receives within the same process 2000 BytesMessages of approximately 500k in size
with integers, doubles, strings, etc embedded within the body of the message. Normally this
task takes 5-7 seconds on a couple of other middeware products we use but with the ActiveMQ
C++ interface it was taking 26 seconds or so. Essentially I made two rather small changes
which cut the time down to 15 seconds, which is approximately a 30% increase in performance.
Both of these changes were done within the DataInputStream.cpp class. First, majority of the
unmarshalling code was calling readFully for 1 byte. For the single byte extraction, I changed
these readFully operations to inputStream->read() which only return a single byte. There
is an incorrectness in the code that assumes that the inputStream->read(buffer, size) operation
will return -1 when inputStream is at its end. This is incorrect. As far as I can tell, read(buffer,
size) always throws an exception at the end rather than returning -1. The second enhancement
is I buffered up 256 characters before appending the string in readString. Appending one character
at a time is very inefficient since it constantly needs to determine if the string object
needs to grow, realloc, copy the characters, etc.

The readString operation is still a major hitter in my profiling. It is calling inputStream->read()
millions of times which is a virtual function. Most strings are tens, hundreds, or thousands
of characters in size. Since it is virtual, it cannot be inlined and they are CPU intensive
when called repeatively. I'm sure CPU usage could be dropped another 30-50% if we could move
the readString operation from the DataInputStream class to each inputStream class. That way
the virtual function is called only once for each string unmarshalling and more inlining can
happen. I'll leave it up to the experts in this group on how they want to proceed.

Everything else seems fairly efficient, at least in the test case I was dealing with. The
only other item that showed up in the radar is the ByteArrayOutputStream::write(unsigned char
c) method. Again in this case, it is constantly realloc, copying, etc when the vector needs
to resize. There is a setBuffer method in place but I need to evaluate it a little further
to see if we can preallocate our own buffer based on the size we already know what we need
up front.

Attached is my diffs. Let me know what you think.

> Performance analysis
> --------------------
>                 Key: AMQCPP-93
>                 URL:
>             Project: ActiveMQ C++ Client
>          Issue Type: Task
>    Affects Versions: 2.0
>            Reporter: Nathan Mittler
>            Assignee: Nathan Mittler
>             Fix For: 2.2
>         Attachments: amqcpp-perf1.patch, amqcpp-perf1v2.patch, bench1.cpp
> Do a performance analysis on openwire vs stomp.

This message is automatically generated by JIRA.
You can reply to this email to add a comment to the issue online.

View raw message