V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
thinkershare
V2EX  ›  Python

如何在 Python 存在多个事件循环时正常使用 mayavi 绘图?

  •  
  •   thinkershare ·
    thinkershare · 2022-06-21 01:06:29 +08:00 · 1608 次点击
    这是一个创建于 878 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我使用 Python 创建了一个 WebSocket 连接, 然后开始监听网络响应, 在接受到网络响应的事件回调中, 将数据使用 Mayavi 绘制到屏幕上, 但我发现一旦启动了 WebSocket 后, Mayavi 就无法绘图. 我猜想是因为这 2 个都要求主线程的事件循环, 现在不知道怎么处理了. fork 整个进程和开一个新进程不在考虑范围, 因为启动新进程代价太多, 用户不能接受如此高的延迟!

    neoblackcap
        1
    neoblackcap  
       2022-06-21 01:24:34 +08:00
    试试多线程 + ioloop
    LeeReamond
        2
    LeeReamond  
       2022-06-21 03:26:39 +08:00   ❤️ 1
    使用进程是很合理的考虑,不想新开的话可以用可复用的设计,不知道为什么不考虑。本身如果你使用线程解决了的话,GIL 不能释放又成了一个问题,会拖慢渲染效率的
    thinkershare
        3
    thinkershare  
    OP
       2022-06-21 13:32:41 +08:00
    @LeeReamond 没找到好的办法, 只能使用多进程, 然后使用 Queue 做数据通讯, 但真的很慢很慢. 你用过 mayavi 库吗? 是否有性能优化建议, 这个库启动非常耗时, 每次至少需要 3-10s, 每次同步的数据数据比较大 1-10MB, 然后还需要从 str->bytes->目标数据结构, 最终体验非常差.
    LeeReamond
        4
    LeeReamond  
       2022-06-21 13:55:10 +08:00
    @thinkershare 不好意思不是很熟悉,只是从常理的角度考虑,即使用子进程,载入不也是启动时载入一次就完事了。所以你的开销应该只有实时通讯传入的数据。而 10M 的数据无论对 socket 收发还是 python 计算来说都不大,处理时间应该在毫秒这个数量级才对
    thinkershare
        5
    thinkershare  
    OP
       2022-06-21 14:30:14 +08:00
    @LeeReamond 2MB 的 base65(本来是 bytes, 但因为某些原因, 我需要将其编码为 base64), 然后还原到 bytes-> 然后转换未 numpy, 然后转换未 tensor, 然后使用 mayavi 显示(10W-20W 个 point cloud), 最终就是非常慢. 反序列化这一部分就已经需要秒级了. 最终完成一次窗口绘制, 时间就超过 5s 了. 主要还是二进制序列化太消耗时间了. 不做二进制序列化又太大, 一次网络纯属 20MB, 都需要 10s(香港到大陆). 我想想该怎么优化.
    thinkershare
        6
    thinkershare  
    OP
       2022-06-21 14:32:54 +08:00
    2MB 的 base64 str(本来是 bytes, 但因为某些原因, 我需要将其编码为 base64), 然后还原到 bytes-> 然后转换为 numpy, 然后转换为 tensor, 然后使用 mayavi 显示(10W-20W 个 point cloud), 最终就是非常慢. 反序列化这一部分就已经需要秒级了. 最终完成一次窗口绘制, 时间就超过 5s 了. 主要还是二进制序列化太消耗时间了. 不做二进制序列化又太大, 一次网络传输 20MB, 大概需要 10s(香港到大陆). 我想想该怎么优化.
    LeeReamond
        7
    LeeReamond  
       2022-06-22 08:23:45 +08:00
    @thinkershare



    你的实现可能有些问题,我测了一下两百万的 f64 矩阵,外套一层 zip 压缩,重新转为 numpy 对象的耗时是 70ms ,如果只是 2M 的流的话我这里执行时间是 8ms 。numpy 的序列化和反序列化效率印象里一直不太行,8ms 并不快,不过感觉不应成为你的瓶颈。传输方面的话,阿里腾讯在香港的机器连内地可以跑百兆的,2M 应该很快。正态分布 f64 压缩后也能压 70%左右的体积,如果你能接受削减一些精度应该能压更多
    thinkershare
        8
    thinkershare  
    OP
       2022-06-22 15:41:18 +08:00
    @LeeReamond 我晚上回去打 log 看下各个地方的耗时, 我现在都没有跨网络, 本机测试延迟都是 1400ms, server, provider, render 都在本机.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1046 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 22:09 · PVG 06:09 · LAX 14:09 · JFK 17:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.