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

时间: 2024-11-18 01:40:44

tinyxml优化之二的相关文章

MySql学习(六) —— 数据库优化理论(二) —— 查询优化技术

逻辑查询优化包括的技术 1)子查询优化  2)视图重写  3)等价谓词重写  4)条件简化  5)外连接消除  6)嵌套连接消除  7)连接消除  8)语义优化 9)非SPJ优化 一.子查询优化 1. 什么是子查询:当一个查询是另一个查询的子部分时,称之为子查询. 2. 查询的子部分,包含的情况: a) 目标列位置:子查询如果位于目标列,则只能是标量子查询,否则数据库可能返回类似“错误:子查询只能返回一个字段 ( [Err] 1242 - Subquery returns more than 1

Hive参数层面优化之二控制Reduce数

Reduce数决定中间或落地文件数,文件大小和Block大小无关. 1.Reduce个数的决定因素 reduce个数的设定极大影响任务执行效率,不指定reduce个数的情况下,Hive会猜测确定一个reduce个数,基于以下两个设定: 参数1:hive.exec.reducers.bytes.per.reducer(每个reduce任务处理的数据量,默认为1000^3=1G) 参数2:hive.exec.reducers.max(每个作业最大的reduce数,默认为999) 计算reducer数

NFS部署及优化(二)

NFS部署及优化(二) 一.如何配置更改文件用户 在B机器上: 在实际生产环境当中,直接用映射过来的nfsnobody用户并不合适 那么如何来指定新建的这个用户呢? 下面我们先来创建一个普通用户,命令如下: [[email protected] shiyan]# useradd user111 [[email protected] shiyan]# cat /etc/passwd |grep user111 user111:x:502:502::/home/user111:/bin/bash #

MySQL性能优化(二)

1.MySQL基础操作 一:MySQL基础操作 1:MySQL表复制 复制表结构 + 复制表数据 create table t3 like t1; --创建一个和t1一样的表,用like(表结构也一样) insert into t3 select * from t1; --t1的数据全部拿过来,注意是表结构一致才select* ,否则选择相应的的字段列插入 create table t1( id int unsigned not null auto_increment primary key,

实例详解Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化(二)

这是本系列的第二篇,内容是 prefetch_related() 函数的用途.实现途径.以及使用方法. 本系列的第一篇在这里 3. prefetch_related() 对于多对多字段(ManyToManyField)和一对多字段,可以使用prefetch_related()来进行优化.或许你会说,没有一个叫OneToManyField的东西啊.实际上 ,ForeignKey就是一个多对一的字段,而被ForeignKey关联的字段就是一对多字段了. 作用和方法 prefetch_related(

Hive架构层面优化之二合理利用中间结果集(单Job)

是针对单个作业,针对本job再怎么优化也不会影响到其他job: Hadoop的负载主要有两部分:CPU负载和IO负载: 问题:机器io开销很大,但是机器的cpu开销较小,另外map输出文件也较大,怎么办? 解决办法:通过设置map的中间输出进行压缩就可以了,这个不会影响最终reduce的输出. 集群中的机器一旦选定了,那么CPU就没的改变了,所以集群的最主要的负载还是IO负载: 压缩技术虽然可以降低IO负载,但是同时也加重了CPU负载,治标不治本,CPU加重了,整体性能还是上不去:如果当前CPU

转 cocos2dx内存优化 (之二)

一.cocos2dx之如何优化内存使用(高级篇) 本文由qinning199原创,转载请注明:http://www.cocos2dx.net/?p=93 一.内存优化原则 为了优化应用内存,你应该知道是什么消耗了你应用的大部分内存,答案就是Texture(纹理)!它几乎占据了90%的应用内存.那么我们应该尽力去减小我们应用的纹理内存使用,否则我们的应用进程可能会被系统杀死. 为了减少内存警告,这里我们给出两个普遍的关于cocos2dx游戏内存优化的指导原则. 1)了解瓶颈,然后解决掉 什么样的纹

黄聪:Discuz!的SEO优化策略二:如何去掉页脚多余的信息

论坛搭建好,首先是把多余的东西都砍掉. 页脚的信息在我看来,都是很多余的信息,如下图: 要怎么消灭掉它们呢? 1.进入 全局 -- 站点信息 2.站点名称改为你的论坛名称,它会出现在内页的标题最末位. 3.我比较喜欢简洁,所以我将网站名称和网站URL都删掉了,当然你也可以设置为自己的论坛名称和域名. 4.打开 template\default\common 目录,找到 footer.htm 文件. 5.查找 <div id="flk" class="y">

CentOS7.4—Apache优化应用二(日志管理)

Apache优化应用二(日志管理)目录第一部分 准备工作第二部分 安装Apache服务第三部分 日志管理一(配置日志分割)第四部分 日志管理二(配置Awstats日志分析软件) 第一部分 准备工作一:服务器:Linux系统-CentOS 7.4:IP地址:192.168.80.10 客户端:以WIN7为例,测试验证结果,与服务器在同一网段:IP地址:192.168.80.2 二:准备压缩包 //apr-1.6.2.tar.gz和apr-util-1.6.0.tar.gz是httpd2.4以后的版