我使用 Python 创建了一个 WebSocket 连接, 然后开始监听网络响应, 在接受到网络响应的事件回调中, 将数据使用 Mayavi 绘制到屏幕上, 但我发现一旦启动了 WebSocket 后, Mayavi 就无法绘图. 我猜想是因为这 2 个都要求主线程的事件循环, 现在不知道怎么处理了. fork 整个进程和开一个新进程不在考虑范围, 因为启动新进程代价太多, 用户不能接受如此高的延迟!
1
neoblackcap 2022-06-21 01:24:34 +08:00
试试多线程 + ioloop
|
2
LeeReamond 2022-06-21 03:26:39 +08:00 1
使用进程是很合理的考虑,不想新开的话可以用可复用的设计,不知道为什么不考虑。本身如果你使用线程解决了的话,GIL 不能释放又成了一个问题,会拖慢渲染效率的
|
3
thinkershare OP @LeeReamond 没找到好的办法, 只能使用多进程, 然后使用 Queue 做数据通讯, 但真的很慢很慢. 你用过 mayavi 库吗? 是否有性能优化建议, 这个库启动非常耗时, 每次至少需要 3-10s, 每次同步的数据数据比较大 1-10MB, 然后还需要从 str->bytes->目标数据结构, 最终体验非常差.
|
4
LeeReamond 2022-06-21 13:55:10 +08:00
@thinkershare 不好意思不是很熟悉,只是从常理的角度考虑,即使用子进程,载入不也是启动时载入一次就完事了。所以你的开销应该只有实时通讯传入的数据。而 10M 的数据无论对 socket 收发还是 python 计算来说都不大,处理时间应该在毫秒这个数量级才对
|
5
thinkershare OP @LeeReamond 2MB 的 base65(本来是 bytes, 但因为某些原因, 我需要将其编码为 base64), 然后还原到 bytes-> 然后转换未 numpy, 然后转换未 tensor, 然后使用 mayavi 显示(10W-20W 个 point cloud), 最终就是非常慢. 反序列化这一部分就已经需要秒级了. 最终完成一次窗口绘制, 时间就超过 5s 了. 主要还是二进制序列化太消耗时间了. 不做二进制序列化又太大, 一次网络纯属 20MB, 都需要 10s(香港到大陆). 我想想该怎么优化.
|
6
thinkershare OP 2MB 的 base64 str(本来是 bytes, 但因为某些原因, 我需要将其编码为 base64), 然后还原到 bytes-> 然后转换为 numpy, 然后转换为 tensor, 然后使用 mayavi 显示(10W-20W 个 point cloud), 最终就是非常慢. 反序列化这一部分就已经需要秒级了. 最终完成一次窗口绘制, 时间就超过 5s 了. 主要还是二进制序列化太消耗时间了. 不做二进制序列化又太大, 一次网络传输 20MB, 大概需要 10s(香港到大陆). 我想想该怎么优化.
|
7
LeeReamond 2022-06-22 08:23:45 +08:00
@thinkershare
你的实现可能有些问题,我测了一下两百万的 f64 矩阵,外套一层 zip 压缩,重新转为 numpy 对象的耗时是 70ms ,如果只是 2M 的流的话我这里执行时间是 8ms 。numpy 的序列化和反序列化效率印象里一直不太行,8ms 并不快,不过感觉不应成为你的瓶颈。传输方面的话,阿里腾讯在香港的机器连内地可以跑百兆的,2M 应该很快。正态分布 f64 压缩后也能压 70%左右的体积,如果你能接受削减一些精度应该能压更多 |
8
thinkershare OP @LeeReamond 我晚上回去打 log 看下各个地方的耗时, 我现在都没有跨网络, 本机测试延迟都是 1400ms, server, provider, render 都在本机.
|