这次工作真是纯粹额外的,如果项目前期策划好,完全可以避免的。
由于曾经接触了一点C、C++等,对于MFC开发有一点点基础,但毕竟不是纯软件方面,所以有点赶鸭子上架的味道。
由于收到了大量的串口数据,数据都是按16进制格式,直接由下位机系统打包发来的,对于这些数据需要数据转换成10进制,然后存成一定的格式,由后续Excel等软件画图出来。
数据量一般十几MB,大的话会达到几十MB。
数据转换的主要过程为:
1. 打开原始数据文件,TXT文件格式;
2. 读取数据,如FE DC等十六进制字符;
3. 转换数据,字符转成数字,A转为10,FF转为255等;
4. 数据处理,十六进制数据转为十进制;
5. 保存文件。
过程非常简单,但就这种处理,在实际编程处理时也会发生种种问题。
第一次是用CString进行处理,读取、转换都比较简单的语句,但实际一使用就发现了问题,当数据量超过1MB,甚至只有八九百KB以上,转换速度就会特别慢,一下子由几分钟需要等到十几分钟以上。
然后就开始各种编程尝试,包括文件打开的优化、数据处理的优化,最终摸索的是,还是最基本的处理方式效率最高:
1. 对于文件打开、读写等操作,CArchive、CFile、FILE等,尽量用简单的FILE进行,速度要快;C语言效率高真不是虚传,能用C 的函数、定义的,还是用C,特别是涉及底层的操作、运算;
2. 对于中间的数据处理,CString对于少量数据还可以对付,但如果使用.format()函数,数据稍微长一点会导致处理时间大大延长;
3. 最终的处理是用了最简单的char字符进行的,定义最简单、逻辑最简单,处理速度最快,彻底杜绝了封装更高的类的使用;
4. 为了省事,开辟了float数组,存储转换后的数据,但最多也就能设置10万组以内的数组,当然最新的C#不知道是否支持更大的数组设置,每次读写文件可以保存近十万条数据;
5. 和原来的比较,速度大大提高,几十MB的文件,一分钟之内就可以处理好,数据数量超过千万条。
初步的小结:
1. 对于大批量的数据处理,效率问题就比较重要了,尽量不要使用封装太复杂的类,虽然使用方便,但会严重影响处理的速度和效率;
2. 在进行实际编码前,还是多比较一下不同处理的方案和步骤,初步分析一下运行的效率;
3. 对于软件、硬件结合的项目,能硬件处理的,就尽量硬件处理,会大大提高项目运行的可靠性,降低软件复杂度和开发难度;如果当时用下位机直接输出转换后的数据,估计就没有这次额外的工作了;
4.项目前期合理规划、分工,降低后续的工作量和难度。
这次上位机的数据处理过程,有些理解了为什么N多的串口接收软件,时间稍长就会死机的问题,只要直接使用现成的封装好的控件,里面基本都会使用CString类,会使用format()函数,在数据量增加到一定程度后,响应时间会大大增加,类似于死机症状,但内部机制如何,没有详细研究,像是内存泄露,被操作系统采取了强制保护措施。
作者: 追忆流年寻梦少年, 来源:面包板社区
链接: https://mbb.eet-china.com/blog/uid-me-855000.html
版权声明:本文为博主原创,未经本人允许,禁止转载!
追忆流年寻梦少年 2020-10-14 09:40
应该说,真是第一次碰到效率问题。
真没有想到,很多封装好的类的效率如此之低,很多现成的控件,能完成基本功能,但长期运行、大量数据存储、大量数据处理等,还是很容易暴露出各种问题。
软件遇到了问题也是压力很大,网上各种搜索,各种案例借鉴,字符串的类几乎都尝试了,File相关的类都试了,处理时间逐步加快,但绝对不是
线性减少时间,而是有点指数方式,使用上C的基本库后,时间嗖一下就上来了。
yzw92 2020-10-13 06:40
火引冰薪 2020-10-12 17:31