pythonhaskellthriftthrift-protocol

Thrift server is really slow for simple operation


I'm running a simple Thrift server (http://thrift.apache.org/) as a cross-language platform between Python (the server) and Haskell (the client). The only data structure that needs to be sent across is a 3-tuple of doubles, so the server/client implementation is also very simple - it was sufficient to just follow the tutorials.

However, it is really, really slow! I'm getting response times of about 0.5s for each server response, when I require times of about 0.1s or lower.

Does anyone have any ideas on how to speed this up? You can see my simple server implementation below:

  1 import sys
  2 
  3 from vision import Vision
  4 from vision.ttypes import *
  5 
  6 from thrift.transport import TSocket
  7 from thrift.transport import TTransport
  8 from thrift.protocol import TBinaryProtocol
  9 from thrift.protocol.TBinaryProtocol import TBinaryProtocolAccelerated
 10 from thrift.server import TServer
 11 
 12 class VisionHandler:
 13   def observe(self):
 14     ret = Position()
 15     ret.x,ret.y,ret.z = (1,2,3)
 16     return ret
 17     
 18 ret = Position()
 20 handler = VisionHandler()
 21 processor = Vision.Processor(handler)
 22 transport = TSocket.TServerSocket(port=9090)
 23 tfactory = TTransport.TBufferedTransportFactory()
 24 pfactory = TBinaryProtocol.TBinaryProtocolFactory()
 25 
 26 server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
 27 
 28 print 'Starting the vision server...'
 29 server.serve()
 30 print 'done.'

The client simply queries this server by running

36   client = do
37     handle <- hOpen ("localhost", PortNumber 9090)
38     let binProto = BinaryProtocol handle
39     return (binProto, binProto)

and then

res <- Client.observe =<< client

As far as I'm aware, this is all pretty standard! Why is it so damn slow??

Thanks!


Solution

  • Aside from great suggestion in Ellioh answer regarding socket options, one of the problem is that your operation seems a bit to small and fine to be handled over the socket, and most of the time is spent in network and similar latencies. Usually one would try to group your calls to transfer more data and do more work in each call. Granularity is very important in network distributed apps, and you would need to find a good measure for good performance.