推荐学习书目
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 · Jun 21, 2022 · 2034 views
    This topic created in 1426 days ago, the information mentioned may be changed or developed.

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

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



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