Browse Source

Decoding speed optimizations

master
Nikita 13 years ago
parent
commit
39e215a528
  1. 26
      pom.xml
  2. 23
      src/main/java/com/corundumstudio/socketio/PacketHandler.java
  3. 3
      src/main/java/com/corundumstudio/socketio/parser/Packet.java
  4. 6
      src/main/java/com/corundumstudio/socketio/parser/PacketType.java
  5. 6
      src/test/java/com/corundumstudio/socketio/PacketHandlerTest.java

26
pom.xml

@ -35,18 +35,18 @@
</developers>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.googlecode.jmockit</groupId>
<artifactId>jmockit</artifactId>
<version>0.999.15</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty</artifactId>
@ -127,12 +127,22 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.5</source>
<target>1.5</target>
<source>1.6</source>
<target>1.6</target>
<optimize>true</optimize>
<showDeprecations>true</showDeprecations>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
<configuration>
<argLine>-Dfile.encoding=utf-8</argLine>
</configuration>
</plugin>
<plugin>
<groupId>com.mycila.maven-license-plugin</groupId>

23
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;
}
}

3
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;

6
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];
}
}

6
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<Packet> 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");

Loading…
Cancel
Save