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!
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.