tinyxml优化之二
原文链接:http://www.cnblogs.com/zouzf/p/4216046.html
tinyxml优化之一说到了效率在差别有三方面的原因:解析的方式、内存分配(字符串操作)、冗余的安全性检查,那么优化就从这些方面着手:
1、修改解析的方式
无论是tinyxml1的逐字符扫描还是tinyxml2的递归解析,最本质的都是扫描每一个字符来进行分析,如果我们知道每一个节点、属性的name和value的长度和位置,在解析的时候按需要移动文本指针,岂不是可以快很多么?
实现思路如下:
(1)、把XML文件读进内存,然后用tinyxml(tinyxml1和tinyxml2都一样)自身的解析方式进行解析;
(2)、获取到解析好的XMLDocument,按照一定的规则把每个节点、每个属性的name和value保存到文本,还要把一些额外的信息如节点间的父子兄弟关系、节点有多少属性、每个节点每个属性的name和value的长度等信息也保存到文本里;
(3)、读取那个特殊格式的文本到内存,根据一定的规则构建出所有的节点,再根据保存进来的额外的信息给每一个节点补充上它的属性信息 以及 节点间的父子兄弟关系。在解析这个文本时,不需要逐字符解析,而是根据先读取到的那些额外的信息就可以得知某个节点有几个属性、每个属性的name和value有多长,这样子就可以让文本指针每次移动多少个字节了~~
2、内存分配(字符串操作)
tinyxml1:不使用STL的话,分配一块内存把XML文件的数据都拷贝过来,修改tinystr类,在解析的时候涉及到字符串操作时不进行内存分配和拷贝操作,而是把tinystr对象的char*直接指向大内存块的对应的位置;如果使用STL,这部分没有什么好修改的,毕竟,给STL::string赋值时,它都是自己管理内存的。
tinyxml2:本身它就会分配一块大内存把XML文本的数据拷贝过来的,解析的时候它自身也是把strpair类的char*直接指向大内存块的某个位置而不会重新分配内存,也没啥好做的。
3、冗余的安全检查
添加新的addElement、addAttribute方法,解析的时候每次添加节点、属性的时候,不检查是否已有同名的节点或者属性;这个检查交由XML文档的提供者来负责吧。其实,这个根本不需要担心,第一步的时候我们需要把用tinyxml自身的解析方法来解析 然后 在根据特定的规则把保存成特定格式的文本,在这一步的解析里,如果XML文本有啥问题也会被检查出来的,提前修正即可。
分析
上面三个步骤,其实第二步没啥用,因为我们项目用到的tinyxml1是使用了STL::string的。。。。剩下的第一步和第三步,明显可以看出第三步是比较简单的,90%的工作量和难度都是在第一步里,但是刚开始我只做了第一步而没有做第三步时,发现效率提高不了多少。。。配合上第三步才有60%~70%的提高,这让人很蛋疼,因为第一步实在是占了所有优化工作的90%以上,都想直接把第一步删掉只保留第三步了,但我没有测试过效果如何。。。。
后来进一步优化的时候发现,在第一步时,可以把那些额外的信息保存成连续的一块,再把所有有用的字符串保存成连续的一块,在解析完之后可以只保留字符串那一块而把额外信息那一块删掉(当然不是直接删掉,而是分配内存把字符串那一块的信息拷贝过来,在解析的时候移动指针时加上一个偏移量即可,解析完即可把带有额外信息和连续字符串那块内存释放掉了),这样子可以让内存比原来减少30%~40%,毕竟,XML文件里所有的双引号、空格、尖括号等没用的信息都被删掉了~~~额外的惊喜
其他方案
后来在和同事讨论的时候也想过一个方案:直接用pugixml来解析,然后再转成tinyxml树,毕竟,相对于tinyxml,pugixml的效果高得吓人(高20~30倍)!后来想了一下,我们第一步的工作可以通过tinyxml的更强一点的安全检查来检查出XML文件是否有些小瑕疵,然后还能减少内存,这都是挺重要的方面,另外,pugixml解析完转成tinyxml树,这一步的消耗估计也是挺大的,总的来说可能这种方案的效率不见得比上面的方案能提高多少(说不准还会低,毕竟,遍历pugixml树来构建tinyxml树。。。),就不考虑了。
终于,可以在不改变原来接口的基础上,使得XML文件解析的效率提高了60%~70%,占用的内存减少了30%~40%,真是莫大的惊喜,要知道,项目有不少XML文件都是上万行的,三万行的文件也有七八个,一个就有3M大~~~通过这个优化,也学到了不少东西~~也知道了自己非常大的一个弱点就是:看代码的能力比较差,有待提高。
代码,后面再贴出来吧,有需要的朋友可以留言。
原文链接:http://www.cnblogs.com/zouzf/p/4216046.html
tinyxml优化之二的更多相关文章
- MySql学习(六) —— 数据库优化理论(二) —— 查询优化技术
逻辑查询优化包括的技术 1)子查询优化 2)视图重写 3)等价谓词重写 4)条件简化 5)外连接消除 6)嵌套连接消除 7)连接消除 8)语义优化 9)非SPJ优化 一.子查询优化 1. ...
- 转 cocos2dx内存优化 (之二)
一.cocos2dx之如何优化内存使用(高级篇) 本文由qinning199原创,转载请注明:http://www.cocos2dx.net/?p=93 一.内存优化原则 为了优化应用内存,你应该知道 ...
- Java Web 前端高性能优化(二)
一.上文回顾 上回我们主要从图片的合并.压缩等方面介绍前端性能优化问题(详见Java Web 前端高性能优化(一)) 本次我们主要从图像BASE64 编码.GZIP压缩.懒加载与预加载以及 OneAP ...
- 【Go】使用压缩文件优化io (二)
原文链接: https://blog.thinkeridea.com/201907/go/compress_file_io_optimization2.html 上一篇文章<使用压缩文件优化io ...
- Linux基础优化(二)
Linux基础优化(二) 一操作系统字符优化 避免出现中文乱码,UTF-8支持中文GBK-Xx支持中文 (一)查看默认编码 [root@centos7 ~]# echo $LANG en_US.UTF ...
- oracle优化原则(二)
SQL优化原则 二.SQL语句编写注意问题 www.2cto.com 下面就某些SQL语句的where子句编写中需要注意的问题作详细介绍.在这些where子句中,即使某些列存在索引,但是由于编写了劣质 ...
- Centos6.5 64linux系统基础优化(二)
1 操作的最小化原则 1)安装系统最小化 2)开启程序服务最小化原则 3)操作最小化原则 4)登陆最小化原则;平时没有需求不用root登陆,要用普通登陆. 2 更改ssh服务默认端口及常规配置 # ...
- SQL 语句优化—— (二) 索引的利用
索引是与表或视图关联的磁盘上结构,可以加快从表或视图中检索行的速度.索引包含由表或视图中的一列或多列生成的键.与书中的索引一样,数据库中的索引使您可以快速找到表或索引视图中的特定信息.索引包含从表或视 ...
- SSE图像算法优化系列二十九:基础的拉普拉斯金字塔融合用于改善图像增强中易出现的过增强问题(一)
拉普拉斯金字塔融合是多图融合相关算法里最简单和最容易实现的一种,我们在看网络上大部分的文章都是在拿那个苹果和橙子融合在一起,变成一个果橙的效果作为例子说明.在这方面确实融合的比较好.但是本文我们主要讲 ...
随机推荐
- Unittest框架概念
1.测试脚手架(test fixture): 测试准备前要做的工作和测试执行完后要做的工作(包括setUp()和tearDown()) 2.测试用例(test case): 最小的测试单元 3.测试套 ...
- 在本地模拟搭建zookeeper集群环境实例
先给一堆学习文档,方便以后查看 官网文档地址大全: OverView(概述) http://zookeeper.apache.org/doc/r3.4.6/zookeeperOver.html Get ...
- Android实例-使用电话拨号器在移动设备上
Android实例-使用电话拨号器在移动设备上 源文地址: http://docwiki.embarcadero.com/RADStudio/XE5/en/Mobile_Tutorial:_Using ...
- SpringCloud落地实践
这几年微服务架构越来越火.伴随着微服务概念的提示,越来越多的组织为了方便开发,结合实际提供很多微服务机构, 之前工作中一直使用dubbo作为微服务框架, dubbo只是专注于服务之间的通讯,所以更灵活 ...
- coreldraw X6 cdrX6下载激活工具
coreldraw X6 cdrX6下载激活工具 百度网盘 CDRX6下载 激活教程什么的请参考 低吟浅唱 博客
- HTTP缓存实现的原理
浏览器是如何知道使用缓存的,其实这都是通过http中,浏览器将最后修改时间发送请求给web服务器,web服务器收到请求后跟服务器上的文档最后修改的时间对比,如果web服务器上最新文档修改时间小于或者等 ...
- Response 和 Request
1. request 对象和 response 对象均由服务器创建. 2. 服务器处理请求的流程: 服务器每次收到请求时, 都会为这个请求开辟一个新的线程; 服务器会把客户端的请求数据封装到 requ ...
- netstat命令——网络,进程,内存
netstat网络.进程.内存 转自:https://www.cnblogs.com/xieshengsen/p/6618993.html https://zhidao.baidu.com/quest ...
- SQL 将列转成字符串并用逗号分隔
SELECT STUFF((SELECT ',' + FieldName FROM TableName FOR XML PATH('')),1,1,'') AS T 其中的逗号可以换成其它字符 转换完 ...
- 四.mysql演示银行转账
代码演示: #conding:utf8 import pymysql import sys class TransferMoney(object): def __init__(self,conn): ...