V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
iamtuzi3333
V2EX  ›  程序员

如何一次性传输海量浮点数

  •  
  •   iamtuzi3333 · 12 天前 · 1726 次点击

    大佬们,现在有一个二维浮点数数组,20005196 ,还有一个数组是 20001 ,整型数组,如何将 2 个数组的数据传给前端,一次性能传完吗,刚才试了下,页面直接卡死,有什么好办法?

    27 条回复    2025-05-13 19:52:13 +08:00
    ipwx
        1
    ipwx  
       12 天前
    变成 JSON 的时候最好 round(value * multiplier),让你的 JSON 不要充斥着 3.333333333333333333333334 这种无效的长度。比如你想保留两位小说,就 multiplier = 100 。到 JS 里面再除回去。
    dcsuibian
        2
    dcsuibian  
       12 天前   ❤️ 2
    2000 乘 5196 ,2000 乘 1 ,楼主用了 markdown 的*了
    rekulas
        3
    rekulas  
       12 天前
    如果只是几千万个的话对大部分客户端来说应该没什么性能压力,最多占些内存,卡应该是你前端处理导致的,优化下处理方式 流式处理或自行处理数据应该就可以了
    guiqiqi
        4
    guiqiqi  
       12 天前
    JSON 可能不太好传输吧,如果不分组传输的情况下;建议 pack 一下,打包成二进制,前端拿到之后用 Buffer unpack 一下,这样效率可能会高很多,如果传输 FP16 的话,前端一次性也就拿到最多 20MB 的数据,异步加载一下应该还是可以的。
    希望有帮到楼主。
    spritecn
        5
    spritecn  
       12 天前
    卡死是渲染问题吧,传这点量的数据也就几 m 的事
    lzxz1234
        6
    lzxz1234  
       12 天前
    可以换个思路,考虑压缩下数量,采样 或者 分步加载
    iamtuzi3333
        7
    iamtuzi3333  
    OP
       12 天前
    @ipwx 明白
    @dcsuibian 是的,用了一个乘号,目前是 2000 行 5196 列的矩阵,另外一个是 2000 行一列。
    @rekulas 现在卡的原因是前端提示接收不到这么多数据,我用页面请求 get 请求提示超出内存了,看了数据大概 210MB ,然后花了十几秒
    X_Del
        8
    X_Del  
       12 天前
    只看数据量还好,优先检查有没有对应数据生成 dom ?比如每个浮点数都对应一个 div 放在页面上。
    一千万个浮点数不一定会卡死页面,但一千万个 div 肯定能卡死页面,必须上 virtualizer
    iamtuzi3333
        9
    iamtuzi3333  
    OP
       12 天前
    @guiqiqi 明白,我试了再打包,没问题,就是前端解包挺麻烦
    @lzxz1234 分布也试了,但是因为数据每十秒会变,这里多次分布请求担心出现不是同一批的数据
    dcsuibian
        10
    dcsuibian  
       12 天前
    数据量大,但不算非常大,刚刚在我电脑上试了下:

    生成 2000 行 5196 列的二维数组,耗时:435ms
    序列化 2000 行 5196 列的二维数组,耗时:1444ms
    写入 2000 行 5196 列的二维数组,耗时:297ms
    反序列化 2000 行 5196 列的二维数组,耗时:1138ms

    JSON 总共也就 190MiB ,这么多数据前端 JSON.parse 一下也就 1.1 秒,不会很卡的
    传输要花一点时间
    fetch 的话,网络请求和.json()方法都是异步的,不会卡的

    所以很明显,就是渲染出了问题,如果你是一个很大的表格,或者都展示在一个 ECharts 图上,那肯定会卡死,优化方法还是挺多的
    aimuz
        11
    aimuz  
       12 天前
    JSONL 呢?流式返回
    iamtuzi3333
        12
    iamtuzi3333  
    OP
       12 天前
    @dcsuibian 大佬,请教一下这里是怎么操作的,我用的 Python ,转的是 list 类型,list[list[float]]以及 list[float],这个传输量这么少的吗
    ufo5260987423
        13
    ufo5260987423  
       12 天前
    double->byte[]->string
    double[][]->byte[][][]->string[][]
    iamtuzi3333
        14
    iamtuzi3333  
    OP
       12 天前
    大佬们,现在用了一个 npz 打包,速度很快,我用的 Python ,代码如下:
    @app.route('/get_data_bin', methods=['GET'])
    def get_data_bin():
    start = time.time()
    data_2d, data_1d = readDataFile(r'C:\wxy\吕博士\data\data_2025-04-17 10-56-00_count2000_pointBytes20784.dat')

    # 将两个数组打包成 .npz 压缩文件到内存
    buf = io.BytesIO()
    np.savez_compressed(buf, data=data_2d.astype(np.float32), timestamps=data_1d.astype(np.float64))
    buf.seek(0)

    print("打包耗时:", round(time.time() - start, 2), "秒")

    return send_file(
    buf,
    as_attachment=True,
    download_name="data.npz",
    mimetype="application/octet-stream"
    )
    ntedshen
        15
    ntedshen  
       12 天前
    var st=new Date().valueOf();
    var arr=[];
    for(let i1=0;i1<2000;i1++){
    var r=[];
    for(let i2=0;i2<5196;i2++){
    r.push(Math.random());
    }
    arr.push(r);
    }
    console.info(new Date().valueOf()-st);
    var s=JSON.stringify(arr);
    console.info(new Date().valueOf()-st);
    JSON.parse(s);
    console.info(new Date().valueOf()-st);
    console.info(s.length);

    VM787:10 185
    VM787:12 1067
    VM787:14 1331
    VM787:15 200255832

    200m 的 json 前端解析也就 300ms 。。。
    这卡和你数据传输没什么关系。。。
    爆内存更没有。。。
    nagisaushio
        16
    nagisaushio  
       12 天前 via Android   ❤️ 1
    这种不该直接传 binary 吗,为什么要 JSON

    float64 的话一共 80M ,float32 就 40M ,加上压缩更少了。
    nagisaushio
        17
    nagisaushio  
       12 天前 via Android
    @nagisaushio 传到前端都不用解码,套一个 Float64Array 就行了
    dcsuibian
        18
    dcsuibian  
       12 天前
    @iamtuzi3333
    [img][/img]

    我帮你试了,也就花了两秒(你可以做个 Loading ),还都花在网络请求上了
    另外如果你直接打开这个链接是不行的
    [img][/img]
    因为浏览器要显示,所以会超出内存

    也就是说这么多数你只要不一下子都显示就没有问题,加载到内存而已
    主要还是看你前端代码要怎么显示
    iamtuzi3333
        19
    iamtuzi3333  
    OP
       12 天前
    @ntedshen 前端处理是没问题,现在是传输过去很慢,花了十几秒
    @nagisaushio 我现在是读取出来,再转为 json ,数据是从 dat 的二进制文件读取出来的,您说的我试试。
    @dcsuibian 谢谢大佬,我就是发现直接打开连接就不行了,现在慢是先要读取文件,再把数据转为 json ,前端显示就是想做瀑布图,数据从头到尾 在一个框中从上到下流水一样,类似瀑布的效果,数据大小代表不同的颜色。
    iamtuzi3333
        20
    iamtuzi3333  
    OP
       12 天前
    刚重新试了下,后端一秒就处理完成
    https://imgur.com/a/l2aQxU3
    前端从请求到接收用了 9 秒多
    https://imgur.com/a/XOhxpnA
    iamtuzi3333
        21
    iamtuzi3333  
    OP
       12 天前
    都花在了传输上,数据大概 200 多 MB ,https://imgur.com/a/9BBQYIY
    ntedshen
        22
    ntedshen  
       12 天前
    @iamtuzi3333 去 network timing 看。。。
    你要不开个 content-encoding: gzip ,透明的。。。
    转 binary 也是有极限的。。。
    iamtuzi3333
        23
    iamtuzi3333  
    OP
       12 天前
    @ntedshen 解决了,直接用的二进制,前端根据字节数来解析,速度瞬间到达 1s 以内,谢谢大佬。
    @nagisaushio 大佬牛逼,前端根据字节数直接读取数据就可以,现在传输就是 41M 左右!
    nagisaushio
        24
    nagisaushio  
       12 天前   ❤️ 3
    iamtuzi3333
        25
    iamtuzi3333  
    OP
       12 天前
    @nagisaushio 弄好了,我现在就是这样,速度非常的快,40M 也是 1s 内的事情!大佬牛逼。
    rrfeng
        26
    rrfeng  
       12 天前
    实时变化的 200M 数据。。。。。。先考虑下带宽吧
    iamtuzi3333
        27
    iamtuzi3333  
    OP
       12 天前
    @rrfeng 现在解决好了,直接二进制传输,40M ,都是在本地,带宽影响倒是不大。
    谢谢各位大佬!!!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1091 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 17:52 · PVG 01:52 · LAX 10:52 · JFK 13:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.