1
votes

Local on Linux. It's about 10 seconds for a 20k message. My guess is my Java is bad and Python is fine.

py client:

def scan(self, msg):
    try:
        print 'begin scan'
        HOST = 'localhost'
        PORT = 33000
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((HOST, PORT));
        s.sendall(msg)
        data = s.recv(1024)
        s.close()
        print 'Received', repr(data)
    except Exception, e:
        print "error: " + str(e)

Java server:

    ServerSocket service = new ServerSocket(33000); 

    while(true) {

    debug("Begin waiting for connection");

    //this spins
    Socket connection = service.accept();

    debug("Connection received from " + connection.getInetAddress().getHostName());

    OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
    BufferedInputStream in = new BufferedInputStream(connection.getInputStream());


    ScanResultsHeader results = new ScanResultsHeader();

        Scanner scanner = new Scanner();
        results = scanner.scan("[email protected]", "123", in);

and

public ScanResultsHeader scan (String userEmail, String imapRetrievalId, BufferedInputStream mimeEmail) throws IOException, FileNotFoundException, MimeException, ScannerException {

    //how fast would it be to just slurp up stream?
    debug("slurp!");
    String slurp = IOUtils.toString(mimeEmail);
    debug("slurped " + slurp.length() + " characters");
    slurp = slurp.toLowerCase();
    debug("lc'ed it");
    //...

My guess is I'm juggling the input streams wrong. One catch is the "BufferedInputStream mimeEmail" signature is required by the library API scan is using, so I'll need to get to that form eventually. But I noticed the simple act of slurping up a string takes ludicrously long so I'm already doing something incorrect.

2
Maybe putting some performance logging on both client and server can help you determine which of the 2 is really slowing thing down. - Alvin
Per my comment to the answer below, I swapped in a C server and confirmed it's lightning fast. Client is fine, connection is fine, it's failing to efficiently "slurp" in IOUtils using streams I've given it. - djechlin

2 Answers

0
votes

Revising my answer....

If you are reading efficiently, and it appears you are, it will only be taking a lot time because either

  • You are creating a new connection every time you send a message which can be very expensive.
  • You are not sending the data as fast as you think.
  • The message is very large (unlikely but it could be)

There are plenty of examples on how to do this and a good library you can use is IOUtils which makes it simpler.

You should be able to send about 200K/s messages over a single socket in Java.


If you have a sends X bytes protocol using Big Endian you can do this.

DataInputStream dis = new DataInputStream( ...
int len = dis.readInt();
byte[] bytes = new byte[len];
dis.readFully(bytes);
String text = new String(bytes, "UTF-8");
0
votes

Original problem was that the client isn't sending an end-of-input so the "slurp" operation keeps waiting for more stuff to cross the connection.

Solution was to implement an application-layer protocol to send the size of the message in advance, then stop listening for more message after that many bytes. I would have preferred a standard library -- something like, FiniteInputStream extends BufferedInputStream and takes a size as an argument, but wrote my own.