python - 为什么 Thrift Binary 协议(protocol)序列化这么慢?

标签 python thrift thrift-protocol

我是节俭的新手。我用 python 写了一个 thrift 服务器,也用 python 写了一个客户端。

这是我的节俭定义:

struct RatingByReport {
    1: required string ticker,
    2: required i32 cnt_institution,
    3: optional list<string> strong_buy,
    4: optional list<string> buy,
    5: optional list<string> neutral,
    6: optional list<string> sell,
    7: optional list<string> strong_sell,
    8: optional i32 cnt_maintain,
    9: optional i32 cnt_upgrade,
    10: optional i32 cnt_downgrade,
    11: optional i32 avg_score,
    12: optional string adjustment
}

struct TableRatingByReport {
    1: required list<string> head,
    2: required list<RatingByReport> body,
    3: optional struct.CadaTranslation translation
}



service china{
    void ping(),
    TableRatingByReport rating_byreport(1:string ticker) throws (1:struct.CadaInternalError error)
}

这是我的服务器端:

handler = StockChinaHandler()
processor = china.Processor(handler)
#startup()

transport = TSocket.TServerSocket(port=30303)
tfactory = TTransport.TBufferedTransportFactory()
pfactory = TBinaryProtocol.TBinaryProtocolFactory()

server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
#server = TProcessPoolServer.TProcessPoolServer(processor, transport,
#        tfactory, pfactory)

print "Start server..."
import cProfile
print >>open('/tmp/test.log', 'w'), cProfile.run('server.serve()',
        sort='cumulative')
#server.serve()
print "done!"

客户端:

# Make socket
transport = TSocket.TSocket('localhost', 30303)

# Buffering is critical. Raw sockets are very slow
transport = TTransport.TBufferedTransport(transport)

# Wrap in a protocol
protocol = TBinaryProtocol.TBinaryProtocol(transport)

# Create a client to use the protocol encoder
client = china.Client(protocol)

# Connect!
transport.open()

client.ping()
print "ping()"

print msg
msg = client.rating_byreport('2012-01-04')
print msg
transport.close()

cProfile 结果:

       ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000  230.968  230.968 <string>:1(<module>)
        1    0.000    0.000  230.968  230.968 TServer.py:74(serve)
        3    0.000    0.000  225.967   75.322 TSocket.py:172(accept)
        3    0.000    0.000  225.967   75.322 socket.py:194(accept)
        3  225.967   75.322  225.967   75.322 {method 'accept' of '_socket.socket' objects}
        5    0.003    0.001    4.993    0.999 china.py:140(process)
        1    0.000    0.000    3.200    3.200 china.py:177(process_rating_byreport)
        1    0.000    0.000    2.366    2.366 china.py:500(write)
        1    0.003    0.003    2.366    2.366 ttypes.py:515(write)
     1455    0.261    0.000    2.363    0.002 ttypes.py:364(write)
   155556    0.246    0.000    1.995    0.000 TCompactProtocol.py:38(nested)
   145880    0.298    0.000    1.640    0.000 TCompactProtocol.py:255(__writeString)
       18    1.370    0.076    1.370    0.076 {method 'recv' of '_socket.socket' objects}
        5    0.000    0.000    1.292    0.258 TCompactProtocol.py:306(readMessageBegin)
       13    0.000    0.000    1.292    0.099 TCompactProtocol.py:286(__readUByte)
       26    0.000    0.000    1.291    0.050 TTransport.py:54(readAll)
       26    0.000    0.000    1.291    0.050 TTransport.py:154(read)
        5    0.000    0.000    1.291    0.258 TSocket.py:101(read)

在我的例子中,TableRatingByReport 实例有一个包含 1400 行的主体(list\),并且它花费了超过 3 秒(函数 *process_rating_byreport*,这是由 thift 自动生成的)来生成二进制内容。我不知道为什么这么慢。

使用json序列化同样的数据,只用了不到200ms。

我想知道我是否使用了不正确的方式来操纵节俭?

谢谢。

最佳答案

如果速度很重要,请使用 TBinaryProtocolAccelerated。它是用 C 实现的,比 TBinaryProtocol 的 Python 实现快大约 10 倍。

此外,在您的基准测试中将原始 JSON 解析与完整的 Thrift 解析进行比较,这不是一个公平的比较。尝试从解析后的 JSON 创建所有 Thrift 对象,看看开销是否来自解析或实例化如此多的 PyObject。

无论如何,如果您关心解析性能并且 JSON 足以满足您的应用程序(即您不使用二进制数据,您不想要一个好的 RPC 接口(interface)等),那么您应该使用它。

关于python - 为什么 Thrift Binary 协议(protocol)序列化这么慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14171227/

相关文章:

python - 如何将 DataFrame 的每一行导出到同一工作簿中的不同工作表?

python - 将 firefox 配置文件传递给远程 webdriver firefox 实例不起作用

rpc - 微服务之间的通信

Thrift可以使用http,但它是二进制通信协议(protocol)?

scala - Spray 是否有 Thrift 编码/解码支持?

python - 从 RequestHandler 继承的类中缺少 self.async_callback

python - 大消息RSA加密和解密不正确

php - 如何使用 PHP Stargate 客户端将数据插入 Hbase 表

erlang - 如何在 Erlang 中加载 Thrift 客户端

java - Thrift:序列化+反序列化更改对象