我把文件重新编码后,加载速度提升300%!(上)

简介: 我把文件重新编码后,加载速度提升300%!

3个月前,我写过一篇关于性能优化的方法论(《前端性能优化思想模型,在自动驾驶领域的实践》),里面有提到过,我对PCD文件进行二进制转码处理后,效果非常好。

但那篇文章主要是分享方法论思想模型,并没有展开聊细节,所以估计很多入门小伙伴看都懒得看就划走了,或者看完没有太多感觉,糊里糊涂的也没多大收获。

我写的东西晦涩难懂,帮不到大家,这怎么能行?这是我的耻辱

那么今天我就拿其中一个案例来展开聊聊,用最通俗的语言,给你抽丝剥茧讲明白。

先看效果!

转码前后文件尺寸对比:(17.8MB vs 4.6MB,压缩率75%

image.png

转码页面加载效果:(ASCII编码,2倍速播放,18秒)

image.png

转码后页面加载效果(二进制编码,2倍速播放,5秒)

image.png

之前也提到过,在自动驾驶点云标注场景下,一次需要加载几十帧的数据文件,如果每一帧文件都是动辄十几二十MB,那即便做异步加载,等待时间之久也是相当令人头大的。

性能优化迫在眉睫!

好,我们先来盘点一下前端手里能用的几个性能优化法宝:

1. 异步加载2. 分片加载,增量渲染3. 资源文件压缩

4. 缓存

本文暂且只讲3,124就先跳过不聊了,之所以摆在这里是想给大家一点启发,告诉你,还有这么些个优化方法呢,感兴趣的评论区交流,最好是关注我,追更,也给我一些动力。

来,我们继续。

聊到文件压缩,不得不提一件有意思的往事。很多人问我,我网名为啥叫ASCII26

那是因为,大学时候学到著名的哈夫曼编码(Huffman Coding),老师给我们布置了一道作业,用哈夫曼编码压缩一段超长文本,比如一部小说。

我觉得这事儿很有意思,就吭哧吭哧开始写算法,写完一运行,文件确实压小了不少,正得意呢,突然发现,压缩文件反向解码的时候出错了,解出来的文件出现了乱码。

这个问题让我定位了好久好久,没日没夜反复调试,怎么都找不到bug在哪。直到有一天,我发现我编码的文本里有一个鬼东西,原文中肉眼不可见,编码后是一个极其容易被忽视的小红点,我用代码读它,发现这东西的ASCII编码值是26。

当然了,是什么原因导致的bug,以及我怎么解决的,我都记不清了(已经十多年了),我只记得,从那天起,我把所有的网名全都变成了ASCII26,算是一个纪念吧,纪念我呕心沥血独自解决了一个难题,也纪念我对编程这件事仍充满着热爱

扯这个小故事给大家放松下,同时,这个小故事本身也是编解码相关。

好啦,回到正题。

那么这次我们要编解码什么呢?我们先来看下我们要处理的文件长什么样。

image.png

这就是PCD文件(自动驾驶点云文件)的冰山一角,其中,1-11行是它的标准头部信息,而12行之后,便是无穷无尽可随意扩展的点云数据。

这里简单提一嘴,有的产商提供的点云数据直接就是bin文件,而有的是pcd文件,还有的甚至是JSON文件,总之,国内的自动驾驶行业现状非常混乱,工程团队素质良莠不齐。

知道PCD文件头部元信息之后,我们把它取出来备用,这一小部分并不会占用太多体积,压不压缩都无所谓,压缩反而不利于后期直接在ThreeJs里引用。

而真正影响文件体积的,是12行之后的点云数据(几十万行),我们观察这一部份的构成,每一行是一个点的信息,用空格分割,分别代表着x,y,zintensity(头部元信息告诉我们的)。

image.png

那么我们要做的就是逐行扫描点云数据,分别将4个参数转写为二进制数据,存入 DataView 中,再使用NodeJS文件流APIcreateWriteStream 将数据写入目标文件,核心代码如下:


// ...省略部分代码
const PARAMS_LENGTH = 4; // [x, y, z, i].length
const AXIS_BYTES_SIZE = 4;
const POINT_BYTES_SIZE = PARAMS_LENGTH * AXIS_BYTES_SIZE;
// 创建一个dataView,窗口长度初始化为 点云数量 * 16 (从头部文件信息可知,一行4个参数,每个参数占4个字节)
const dataview = new DataView(new ArrayBuffer(POINT_BYTES_SIZE * points.length));
points.forEach((pointString, rowIndex) => {
  // 将点从字符串中取出来,即'x y z i' => [x, y, z, i]
  const point = pointString.split(' ');
  // 逐个参数处理,塞入dataview中
  point.forEach((axis, axisIndex) => {
    dataview.setFloat32(rowIndex * POINT_BYTES_SIZE + axisIndex * PARAMS_LENGTH, Number(axis), true)
  })
})
const wstream = fs.createWriteStream(output, 'binary');
// 写回头部信息
wstream.write(getPCDHeaderString(points.length))
// 写入点云信息
wstream.write(Buffer.from(dataview.buffer))
wstream.end(() => console.log('写入成功!'));
相关实践学习
基于Hologres轻量实时的高性能OLAP分析
本教程基于GitHub Archive公开数据集,通过DataWorks将GitHub中的项⽬、行为等20多种事件类型数据实时采集至Hologres进行分析,同时使用DataV内置模板,快速搭建实时可视化数据大屏,从开发者、项⽬、编程语⾔等多个维度了解GitHub实时数据变化情况。
阿里云实时数仓实战 - 用户行为数仓搭建
课程简介 1)学习搭建一个数据仓库的过程,理解数据在整个数仓架构的从采集、存储、计算、输出、展示的整个业务流程。 2)整个数仓体系完全搭建在阿里云架构上,理解并学会运用各个服务组件,了解各个组件之间如何配合联动。 3 )前置知识要求:熟练掌握 SQL 语法熟悉 Linux 命令,对 Hadoop 大数据体系有一定的了解   课程大纲 第一章 了解数据仓库概念 初步了解数据仓库是干什么的 第二章 按照企业开发的标准去搭建一个数据仓库 数据仓库的需求是什么 架构 怎么选型怎么购买服务器 第三章 数据生成模块 用户形成数据的一个准备 按照企业的标准,准备了十一张用户行为表 方便使用 第四章 采集模块的搭建 购买阿里云服务器 安装 JDK 安装 Flume 第五章 用户行为数据仓库 严格按照企业的标准开发 第六章 搭建业务数仓理论基础和对表的分类同步 第七章 业务数仓的搭建  业务行为数仓效果图  
目录
相关文章
|
机器学习/深度学习 Web App开发 编解码
最高增强至1440p,阿里云发布端侧实时超分工具,低成本实现高画质
近日,阿里云机器学习PAI团队发布一键端侧超分工具,可实现在设备和网络带宽不变的情况下,将移动端视频分辨率提升1倍,最高可增强至1440p,将大幅提升终端用户的观看体验,该技术目前已在优酷、夸克、UC浏览器等多个APP中广泛应用。
最高增强至1440p,阿里云发布端侧实时超分工具,低成本实现高画质
|
9月前
|
缓存 异构计算
DashInfer-VLM,多模态SOTA推理性能,超vLLM!
DashInfer-VLM是一个针对于视觉多模态大模型VLM的推理架构,特别优化了Qwen VL模型的推理加速,DashInfer-VLM和其他的VLM的推理加速框架最大的区别是, 它把VIT部分和LLM部分进行了分离,并且VIT和LLM的运行是并行运行,不互相干扰。
1011 16
|
定位技术 数据处理
合成孔径SAR雷达成像成(RDA和CSA)(Matlab代码实现)
合成孔径SAR雷达成像成(RDA和CSA)(Matlab代码实现)
333 0
|
监控 关系型数据库 MySQL
zabbix 简单介绍 及部署
zabbix 简单介绍 及部署
|
安全
猿大师办公助手在线编辑微软Office/金山wps网页组件COM加载项启用说明
猿大师办公助手是一款独特的在线编辑Office插件,不同于其他厂商的弹窗模式,它真正实现了网页内嵌本机Office。其COM加载项可在Office主菜单栏增加PageHi子菜单,提供文件保存、打印等功能,并能控制文档操作权限。安装后,默认自动启动COM加载项,但需注意可能被禁用或拦截,必要时需手动启用。对于WPS和微软Office,均有详细的启用步骤。
283 5
猿大师办公助手在线编辑微软Office/金山wps网页组件COM加载项启用说明
|
算法
Threejs中使用astar(A*)算法寻路导航,Threejs寻路定位导航
Threejs中使用astar(A*)算法寻路导航,Threejs寻路定位导航
891 0
Threejs中使用astar(A*)算法寻路导航,Threejs寻路定位导航
|
前端开发 JavaScript UED
|
JSON 前端开发 Java
前端axios传参总结
该文介绍了在前后端分离的开发中,前端使用axios向后端Spring传递参数的两种主要方法。针对@RequestParam注解,推荐使用params传参,将参数格式化为x-www-form-urlencoded,或者使用FormData和qs.stringify。对于@RequestBody,Axios的data传参默认为JSON格式,直接传入对象即可。
378 0
|
Web App开发 运维 监控
深入探索Linux命令pwdx:揭秘进程工作目录的秘密
`pwdx`命令在Linux中用于显示指定进程的工作目录,基于`/proc`文件系统获取实时信息。简单易用,如`pwdx 1234`显示PID为1234的进程目录。结合`ps`和`pgrep`等命令可扩展使用,如查看所有进程或特定进程(如Firefox)的目录。使用时注意权限、进程ID的有效性和与其他命令的配合。查阅`man pwdx`获取更多帮助。
|
XML 前端开发 JavaScript
前端网络请求真的搞懂了吗?解密前端参数传递方式,让开发更从容(一)
前端网络请求真的搞懂了吗?解密前端参数传递方式,让开发更从容