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

120 天前
 iamtuzi3333

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

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

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

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

所以很明显,就是渲染出了问题,如果你是一个很大的表格,或者都展示在一个 ECharts 图上,那肯定会卡死,优化方法还是挺多的
aimuz
120 天前
JSONL 呢?流式返回
iamtuzi3333
120 天前
@dcsuibian 大佬,请教一下这里是怎么操作的,我用的 Python ,转的是 list 类型,list[list[float]]以及 list[float],这个传输量这么少的吗
ufo5260987423
120 天前
double->byte[]->string
double[][]->byte[][][]->string[][]
iamtuzi3333
120 天前
大佬们,现在用了一个 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
120 天前
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
120 天前
这种不该直接传 binary 吗,为什么要 JSON

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

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

也就是说这么多数你只要不一下子都显示就没有问题,加载到内存而已
主要还是看你前端代码要怎么显示
iamtuzi3333
120 天前
@ntedshen 前端处理是没问题,现在是传输过去很慢,花了十几秒
@nagisaushio 我现在是读取出来,再转为 json ,数据是从 dat 的二进制文件读取出来的,您说的我试试。
@dcsuibian 谢谢大佬,我就是发现直接打开连接就不行了,现在慢是先要读取文件,再把数据转为 json ,前端显示就是想做瀑布图,数据从头到尾 在一个框中从上到下流水一样,类似瀑布的效果,数据大小代表不同的颜色。
iamtuzi3333
120 天前
刚重新试了下,后端一秒就处理完成
https://imgur.com/a/l2aQxU3
前端从请求到接收用了 9 秒多
https://imgur.com/a/XOhxpnA

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1131507

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX