From 37b5e0e004e4b822ca2841b2a3b91743c4f7af1b Mon Sep 17 00:00:00 2001 From: Nikita Date: Thu, 24 May 2012 13:56:20 +0400 Subject: [PATCH] Decoding speed up --- checkstyle.xml | 4 +- .../socketio/parser/Decoder.java | 87 ++++++++++--------- .../socketio/PacketHandlerTest.java | 2 +- 3 files changed, 52 insertions(+), 41 deletions(-) diff --git a/checkstyle.xml b/checkstyle.xml index 8988e75..620ca44 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -143,7 +143,9 @@ - + + + diff --git a/src/main/java/com/corundumstudio/socketio/parser/Decoder.java b/src/main/java/com/corundumstudio/socketio/parser/Decoder.java index 311c65f..61e1548 100644 --- a/src/main/java/com/corundumstudio/socketio/parser/Decoder.java +++ b/src/main/java/com/corundumstudio/socketio/parser/Decoder.java @@ -43,14 +43,14 @@ public class Decoder { } // fastest way to parse chars to int - private long parseLong(byte[] chars) { - return parseLong(chars, chars.length); + private long parseLong(ChannelBuffer chars) { + return parseLong(chars, chars.readerIndex() + chars.readableBytes()); } - private long parseLong(byte[] chars, int length) { + private long parseLong(ChannelBuffer chars, int length) { long result = 0; - for (int i = 0; i < length; i++) { - int digit = ((int)chars[i] & 0xF); + for (int i = chars.readerIndex(); i < length; i++) { + int digit = ((int)chars.getByte(i) & 0xF); for (int j = 0; j < length-1-i; j++) { digit *= 10; } @@ -106,11 +106,11 @@ public class Decoder { endpoint = endpointBuffer.toString(); } - readerIndex += 1; - byte[] data = null; - if (buffer.readableBytes() - readerIndex > 0) { - data = new byte[buffer.readableBytes() - readerIndex]; - buffer.getBytes(readerIndex, data); + if (buffer.readableBytes() == readerIndex) { + buffer.readerIndex(buffer.readableBytes()); + } else { + readerIndex += 1; + buffer.readerIndex(readerIndex); } Packet packet = new Packet(type); @@ -125,11 +125,11 @@ public class Decoder { } switch (type) { - case ERROR: - if (data == null) { + case ERROR: { + if (!buffer.readable()) { break; } - String[] pieces = new String(data).split("\\+"); + String[] pieces = buffer.toString(CharsetUtil.UTF_8).split("\\+"); if (pieces.length > 0 && pieces[0].trim().length() > 0) { ErrorReason reason = ErrorReason.valueOf(Integer.valueOf(pieces[0])); packet.setReason(reason); @@ -139,42 +139,49 @@ public class Decoder { } } break; + } - case MESSAGE: - if (data != null) { - packet.setData(new String(data)); + case MESSAGE: { + if (buffer.readable()) { + packet.setData(buffer.toString(CharsetUtil.UTF_8)); } else { packet.setData(""); } break; + } - case EVENT: - Event event = objectMapper.readValue(data, Event.class); + case EVENT: { + ChannelBufferInputStream in = new ChannelBufferInputStream(buffer); + Event event = objectMapper.readValue(in, Event.class); packet.setName(event.getName()); if (event.getArgs() != null) { packet.setArgs(event.getArgs()); } break; + } - case JSON: - Object obj = objectMapper.readValue(data, Object.class); + case JSON: { + ChannelBufferInputStream in = new ChannelBufferInputStream(buffer); + Object obj = objectMapper.readValue(in, Object.class); packet.setData(obj); break; + } - case CONNECT: - if (data != null) { - packet.setQs(new String(data)); + case CONNECT: { + if (buffer.readable()) { + packet.setQs(buffer.toString(CharsetUtil.UTF_8)); } break; + } - case ACK: - if (data == null) { + case ACK: { + if (!buffer.readable()) { break; } boolean validFormat = true; int plusIndex = -1; - for (int i = 0; i < data.length; i++) { - byte dataChar = data[i]; + for (int i = buffer.readerIndex(); i < buffer.readerIndex() + buffer.readableBytes(); i++) { + byte dataChar = buffer.getByte(i); if (!Character.isDigit(dataChar)) { if (dataChar == '+') { plusIndex = i; @@ -190,15 +197,18 @@ public class Decoder { } if (plusIndex == -1) { - packet.setAckId(parseLong(data)); + packet.setAckId(parseLong(buffer)); break; } else { - packet.setAckId(parseLong(data, plusIndex)); - buffer.readerIndex(readerIndex+plusIndex+1); - List args = objectMapper.readValue(new ChannelBufferInputStream(buffer), List.class); + packet.setAckId(parseLong(buffer, plusIndex)); + buffer.readerIndex(plusIndex+1); + + ChannelBufferInputStream in = new ChannelBufferInputStream(buffer); + List args = objectMapper.readValue(in, List.class); packet.setArgs(args); } break; + } case DISCONNECT: case HEARTBEAT: @@ -227,13 +237,13 @@ public class Decoder { Integer len = extractLength(buffer); - ChannelBuffer frame = buffer.slice(buffer.readerIndex(), len); + int startIndex = buffer.readerIndex(); + ChannelBuffer frame = buffer.slice(startIndex, len); Packet packet = decodePacket(frame); - buffer.readerIndex(buffer.readerIndex() + len); + buffer.readerIndex(startIndex + len); return packet; } else { Packet packet = decodePacket(buffer); - buffer.readerIndex(buffer.readableBytes()); return packet; } } @@ -251,15 +261,14 @@ public class Decoder { } private long parseLengthHeader(ChannelBuffer buffer) { - int delimiterIndex = ChannelBuffers.indexOf(buffer, buffer.readerIndex(), buffer.capacity(), delimiterFinder); + int delimiterIndex = ChannelBuffers.indexOf(buffer, buffer.readerIndex(), buffer.readerIndex() + buffer.readableBytes(), delimiterFinder); if (delimiterIndex == -1) { throw new DecoderException("Can't find tail delimiter"); } - byte[] digits = new byte[delimiterIndex - buffer.readerIndex()];; - buffer.getBytes(buffer.readerIndex(), digits); - buffer.readerIndex(buffer.readerIndex() + digits.length + Packet.DELIMITER_BYTES.length); - return parseLong(digits); + long len = parseLong(buffer, delimiterIndex); + buffer.readerIndex(delimiterIndex + Packet.DELIMITER_BYTES.length); + return len; } private boolean isCurrentDelimiter(ChannelBuffer buffer, int index) { diff --git a/src/test/java/com/corundumstudio/socketio/PacketHandlerTest.java b/src/test/java/com/corundumstudio/socketio/PacketHandlerTest.java index a455513..60d2af6 100644 --- a/src/test/java/com/corundumstudio/socketio/PacketHandlerTest.java +++ b/src/test/java/com/corundumstudio/socketio/PacketHandlerTest.java @@ -141,7 +141,7 @@ public class PacketHandlerTest { } long end = System.currentTimeMillis() - start; System.out.println(end + "ms"); - // 1143ms + // 670ms }