package org.simpleframework.http.message;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.text.DecimalFormat;
import junit.framework.TestCase;
import org.simpleframework.common.thread.ConcurrentExecutor;
import org.simpleframework.http.core.ThreadDumper;
import org.simpleframework.transport.SocketTransport;
import org.simpleframework.transport.SocketWrapper;
import org.simpleframework.transport.TransportCursor;
import org.simpleframework.transport.reactor.ExecutorReactor;
import org.simpleframework.transport.reactor.Reactor;
import org.simpleframework.transport.trace.Trace;
public class SocketTransportPerformanceTest extends TestCase {
private static final int ITERATIONS = 1000000;
private static final byte[] SOURCE_1 =
("POST /index.html HTTP/1.0\r\n"+
"Content-Type: application/x-www-form-urlencoded\r\n"+
"Content-Length: 42\r\n"+
"Transfer-Encoding: chunked\r\n"+
"Accept: image/gif;q=1.0,\r\n image/jpeg;q=0.8,\r\n"+
" \t\t image/png;\t\r\n\t"+
" q=1.0,*;q=0.1\r\n"+
"Accept-Language: fr;q=0.1, en-us;q=0.4, en-gb; q=0.8, en;q=0.7\r\n"+
"Host: some.host.com \r\n"+
"Cookie: $Version=1; UID=1234-5678; $Path=/; $Domain=.host.com\r\n"+
"Cookie: $Version=1; NAME=\"Niall Gallagher\"; $path=\"/\"\r\n"+
"\r\n").getBytes();
private static final byte[] SOURCE_2 =
("GET /tmp/amazon_files/21lP7I1XB5L.jpg HTTP/1.1\r\n"+
"Accept-Encoding: gzip, deflate\r\n"+
"Connection: keep-alive\r\n"+
"Referer: http://localhost:9090/tmp/amazon.htm\r\n"+
"Cache-Control: max-age=0\r\n"+
"Host: localhost:9090\r\n"+
"Accept-Language: en-US\r\n"+
"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Version/3.1 Safari/525.13\r\n"+
"Accept: */*\r\n" +
"\r\n").getBytes();
private static final byte[] SOURCE_3 =
("GET /tmp/amazon_files/in-your-city-blue-large._V256095983_.gif HTTP/1.1Accept-Encoding: gzip, deflate\r\n"+
"Connection: keep-alive\r\n"+
"Referer: http://localhost:9090/tmp/amazon.htm\r\n"+
"Cache-Control: max-age=0\r\n"+
"Host: localhost:9090\r\n"+
"Accept-Language: en-US\r\n"+
"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Version/3.1 Safari/525.13\r\n"+
"Accept: */*\r\n"+
"\r\n").getBytes();
private static final byte[] SOURCE_4 =
("GET /tmp/amazon_files/narrowtimer_transparent._V47062518_.gif HTTP/1.1\r\n"+
"Accept-Encoding: gzip, deflate\r\n"+
"Connection: keep-alive\r\n"+
"Referer: http://localhost:9090/tmp/amazon.htm\r\n"+
"Cache-Control: max-age=0\r\n"+
"Host: localhost:9090\r\n"+
"Accept-Language: en-US\r\n"+
"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Version/3.1 Safari/525.13\r\n"+
"Accept: */*\r\n"+
"\r\n").getBytes();
public void testPerformance() throws Exception {
SocketAddress address = new InetSocketAddress("localhost", 44455);
ServerSocketChannel server = ServerSocketChannel.open();
server.configureBlocking(false);
server.bind(address);
final SocketChannel writer = SocketChannel.open(address);
writer.configureBlocking(true);
writer.finishConnect();
Thread.sleep(1000);
SocketChannel reader = server.accept();
while(!reader.finishConnect()) {
Thread.sleep(1000);
}
while(!writer.finishConnect()) {
Thread.sleep(1000);
}
DecimalFormat format = new DecimalFormat("###,###,###,###,###.###");
ConcurrentExecutor executor = new ConcurrentExecutor(SocketTransport.class, 10);
Reactor reactor = new ExecutorReactor(executor);
Trace trace = new MockTrace();
SocketWrapper wrapper = new SocketWrapper(reader, trace);
SocketTransport transport = new SocketTransport(wrapper, reactor);
TransportCursor cursor = new TransportCursor(transport);
ThreadDumper dumper = new ThreadDumper();
Thread thread = new Thread() {
public void run() {
try {
for(int i = 0; i < ITERATIONS; i++) {
writer.write(ByteBuffer.wrap(SOURCE_1));
writer.write(ByteBuffer.wrap(SOURCE_2));
writer.write(ByteBuffer.wrap(SOURCE_3));
writer.write(ByteBuffer.wrap(SOURCE_4));
}
writer.close();
} catch(Exception e){
e.printStackTrace();
}
}
};
dumper.start();
thread.start();
long start = System.currentTimeMillis();
int count = 0;
while(true) {
RequestConsumer header = new RequestConsumer();
while(!header.isFinished()) {
header.consume(cursor);
}
header.getPath().getPath(); // parse address also
int ready = cursor.ready();
if(count++ % 50000 == 0) {
System.err.println("Done: " +format.format(count) + " in " + (System.currentTimeMillis()-start) + " ms");
}
if(ready == -1) {
break;
}
}
long finish = System.currentTimeMillis();
long duration = finish - start;
System.err.printf("count=%s time=%s performance=%s (per/ms) performance=%s (per/sec)s%n", format.format(count), duration, format.format(count/duration), format.format(count/(duration/1000)));
thread.join();
executor.stop();
reactor.stop();
dumper.kill();
}
private static class MockTrace implements Trace {
public void trace(Object event) {}
public void trace(Object event, Object value) {}
}
public static void main(String[] list) throws Exception {
new SocketTransportPerformanceTest().testPerformance();
}
}