mina-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Emmanuel L├ęcharny <elecha...@gmail.com>
Subject [MINA 3] Performances
Date Fri, 04 Jan 2013 16:51:37 GMT
Hi !

I conducted some profiling sessions today, to see where we were spening
some spurious CPU in MINA3. When I first did some tests, I was able to
process 1 million 10 bytes messages in 75 seconds (the message is
written by the client, read by the server, which returns a 1 bte message
to the client). This is the very same test than the one Jeff wrote for
MINA 2 and Netty.

After a bit of analysis, I was able to lower this number to 57 seconds.

Now, here are the numbers for MINA 3, MINA 2 and Netty, for 1M messages :

Mina3 client/ Mina3 server : 10bytes msgs in 57.8 secs | 1k msgs in 53.2
secs | 10k msgs in 66.1 secs
Mina2 client/ Mina2 server : 10bytes msgs in 53.4 secs | 1k msgs in 52.4
secs | 10k msgs in 75.6 secs
Netty client/ Mina2 server :10bytes msgs in 51.4 secs | 1k msgs in 49.6
secs | 10k msgs in 74.7 secs

(we currently don't have a Netty server)

So bottom line, MINA 3 is slower than any other combinaison, despite the
minimal features we have injected, except for big messages. Is this a
problem ? Well, yes and no.

There are some very good reasons for MINA 3 to be slower : we call the
selector.select() method for every message we have to send. This is the
most expensive part of the code, and it's not something we can improve :
we don't have any way to make select() go faster.

OTOH, we could call select() less often. Right now, what we do is that
everytime we exit from a select(), we process all the activated
SelectionKey we get. This is done by calling the ready() method, with
flags indicating which event we have to process (OP_READ and OP_WRITE

The ready() method processes the connect, read, wrate and accept events,
one after the other. The thing here is that if a read results in some
writes, the writes will be processed in the next select() loop, when in
Netty and MINA2 it's potentially processed just afterward, in the same
select() loop.

We can bypass this extra loop most of the time, as soon as the channel
is ready. The idea is to push the message into the channel, if we don't
have anything in the writeQueue, and we are done. If the writeQueue is
not empty, we simply push the message in the queue. Last, not least, if
we weren't able to write all the message, we push the remaining message
on the writeQueue, set the SelectKey OP_WRITE to true, and wake up the
selector. That would save us a lot of CPU for small messages.

I will try to do that.

Emmanuel L├ęcharny

View raw message