From 39e215a528b126ccf7274a2b897831106cf35f9c Mon Sep 17 00:00:00 2001 From: Nikita Date: Sat, 12 May 2012 22:55:06 +0400 Subject: [PATCH] Decoding speed optimizations --- pom.xml | 26 +++++++++++++------ .../socketio/PacketHandler.java | 23 ++++++++-------- .../socketio/parser/Packet.java | 3 +++ .../socketio/parser/PacketType.java | 6 +++-- .../socketio/PacketHandlerTest.java | 6 +++-- 5 files changed, 41 insertions(+), 23 deletions(-) diff --git a/pom.xml b/pom.xml index 802e24e..4894d2d 100644 --- a/pom.xml +++ b/pom.xml @@ -35,18 +35,18 @@ - - junit - junit - 4.10 - test - com.googlecode.jmockit jmockit 0.999.15 test + + junit + junit + 4.10 + test + io.netty netty @@ -127,12 +127,22 @@ maven-compiler-plugin 2.3.2 - 1.5 - 1.5 + 1.6 + 1.6 true true + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + + -Dfile.encoding=utf-8 + + + com.mycila.maven-license-plugin diff --git a/src/main/java/com/corundumstudio/socketio/PacketHandler.java b/src/main/java/com/corundumstudio/socketio/PacketHandler.java index 067e114..761f546 100644 --- a/src/main/java/com/corundumstudio/socketio/PacketHandler.java +++ b/src/main/java/com/corundumstudio/socketio/PacketHandler.java @@ -3,10 +3,10 @@ package com.corundumstudio.socketio; import java.io.IOException; import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.ChannelHandler.Sharable; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelUpstreamHandler; -import org.jboss.netty.channel.ChannelHandler.Sharable; import org.jboss.netty.util.CharsetUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,13 +49,11 @@ public class PacketHandler extends SimpleChannelUpstreamHandler { } } - // TODO use ForkJoin private Packet decode(ChannelBuffer buffer) throws IOException { - char delimiter = getChar(buffer, buffer.readerIndex()); - if (delimiter == Packet.DELIMITER) { + if (isCurrentDelimiter(buffer, buffer.readerIndex())) { StringBuilder length = new StringBuilder(4); - for (int i = buffer.readerIndex() + 2 + 1; i < buffer.readerIndex() + buffer.readableBytes(); i++) { - if (getChar(buffer, i) == Packet.DELIMITER) { + for (int i = buffer.readerIndex() + Packet.DELIMITER_BYTES.length; i < buffer.readerIndex() + buffer.readableBytes(); i++) { + if (isCurrentDelimiter(buffer, i)) { break; } else { length.append((char)buffer.getUnsignedByte(i)); @@ -63,7 +61,7 @@ public class PacketHandler extends SimpleChannelUpstreamHandler { } Integer len = Integer.valueOf(length.toString()); - int startIndex = buffer.readerIndex() + 3 + length.length() + 3; + int startIndex = buffer.readerIndex() + Packet.DELIMITER_BYTES.length + length.length() + Packet.DELIMITER_BYTES.length; ChannelBuffer frame = buffer.slice(startIndex, len); Packet packet = decoder.decodePacket(frame.toString(CharsetUtil.UTF_8)); buffer.readerIndex(startIndex + len); @@ -75,10 +73,13 @@ public class PacketHandler extends SimpleChannelUpstreamHandler { } } - // TODO refactor it - private char getChar(ChannelBuffer buffer, int index) { - byte[] bytes = {buffer.getByte(index), buffer.getByte(index + 1)}; - return new String(bytes).charAt(0); + private boolean isCurrentDelimiter(ChannelBuffer buffer, int index) { + for (int i = 0; i < Packet.DELIMITER_BYTES.length; i++) { + if (buffer.getByte(index + i) != Packet.DELIMITER_BYTES[i]) { + return false; + } + } + return true; } } diff --git a/src/main/java/com/corundumstudio/socketio/parser/Packet.java b/src/main/java/com/corundumstudio/socketio/parser/Packet.java index ced23d7..fdbc3ef 100644 --- a/src/main/java/com/corundumstudio/socketio/parser/Packet.java +++ b/src/main/java/com/corundumstudio/socketio/parser/Packet.java @@ -18,9 +18,12 @@ package com.corundumstudio.socketio.parser; import java.util.Collections; import java.util.List; +import org.jboss.netty.util.CharsetUtil; + public class Packet { public static final char DELIMITER = '\ufffd'; + public static final byte[] DELIMITER_BYTES = new String(new char[] {DELIMITER}).getBytes(CharsetUtil.UTF_8); public static final Packet NULL_INSTANCE = new Packet(null); private final PacketType type; diff --git a/src/main/java/com/corundumstudio/socketio/parser/PacketType.java b/src/main/java/com/corundumstudio/socketio/parser/PacketType.java index 976248d..8ca82f2 100644 --- a/src/main/java/com/corundumstudio/socketio/parser/PacketType.java +++ b/src/main/java/com/corundumstudio/socketio/parser/PacketType.java @@ -19,7 +19,9 @@ public enum PacketType { DISCONNECT(0), CONNECT(1), HEARTBEAT(2), MESSAGE(3), JSON(4), EVENT(5), ACK(6), ERROR(7), NOOP(8); - private int value; + // optimization founded by profiler + private static final PacketType[] someValues = values(); + private final int value; PacketType(int value) { this.value = value; @@ -30,7 +32,7 @@ public enum PacketType { } public static PacketType valueOf(int value) { - return values()[value]; + return someValues[value]; } } diff --git a/src/test/java/com/corundumstudio/socketio/PacketHandlerTest.java b/src/test/java/com/corundumstudio/socketio/PacketHandlerTest.java index 9999030..c11e506 100644 --- a/src/test/java/com/corundumstudio/socketio/PacketHandlerTest.java +++ b/src/test/java/com/corundumstudio/socketio/PacketHandlerTest.java @@ -31,6 +31,8 @@ public class PacketHandlerTest { private Encoder encoder = new Encoder(map); @Mocked private Channel channel; + @Mocked + private SocketIOClient client; @Test public void testOnePacket() throws Exception { @@ -96,7 +98,7 @@ public class PacketHandlerTest { PacketHandler handler, List packets) throws Exception { String str = encoder.encodePackets(packets); ChannelBuffer buffer = ChannelBuffers.wrappedBuffer(str.getBytes()); - handler.messageReceived(null, new UpstreamMessageEvent(channel, new PacketsMessage(null, buffer), null)); + handler.messageReceived(null, new UpstreamMessageEvent(channel, new PacketsMessage(client, buffer), null)); Assert.assertEquals(packets.size(), invocations.get()); } @@ -112,7 +114,7 @@ public class PacketHandlerTest { ChannelBuffer buffer = ChannelBuffers.wrappedBuffer("\ufffd5\ufffd3:::5\ufffd7\ufffd3:::53d\ufffd3\ufffd0::\ufffd5\ufffd3:::5\ufffd7\ufffd3:::53d\ufffd3\ufffd0::\ufffd5\ufffd3:::5\ufffd7\ufffd3:::53d\ufffd3\ufffd0::\ufffd5\ufffd3:::5\ufffd7\ufffd3:::53d\ufffd3\ufffd0::\ufffd5\ufffd3:::5\ufffd7\ufffd3:::53d\ufffd3\ufffd0::".getBytes()); for (int i = 0; i < 50000; i++) { ChannelBuffer t = buffer.copy(); - handler.messageReceived(null, new UpstreamMessageEvent(channel, new PacketsMessage(null, t), null)); + handler.messageReceived(null, new UpstreamMessageEvent(channel, new PacketsMessage(client, t), null)); } long end = System.currentTimeMillis() - start; System.out.println(end + "ms");