QtInternal 之 高效使用QString(使用QLatin1String,QStringRef,QStringBuilder,QStringMatcher等相关类)
注意:本文翻译自 http://developer.qt.nokia.com 中的 UsingQStringEffectively ,中文译文见 简体中文版 ,如果你对翻译wiki感兴趣,请参考Wiki中文帮助
本文解释了QString相关的各个类的用途。
QLatin1String:避免操作符 "==" 中隐含的 malloc
从C字符串创建一个QString可能会涉及到malloc。举例来说,下面的代码可能会有一个隐式malloc调用的代价。
if (fruit == "apple") { ... } // possibly hidden malloc
QString 为C字符串提供了重载的比较函数 QString::operator==(const char *)。而C字符串的编码是使用QTextCodec::setCodecForCStrings()来确定的。Qt 通过提供一个特殊的比较Unicode字符串(fruit)和Latin-1字符串('apple')的函数来执行上述比较操作。该比较操作很快且不需要malloc。
尽管如此,当QTextCodec::setCodecForCString被设置后,"apple" 将通过 QString::fromAscii() 被转换成一个QString。这意味这QString在执行比较之前将为字符串 "apple" 分配内存并创建C字符串的一个深拷贝!
应用程序开发者在main()函数中设置 QTextCodec::setCodecForCString() 却没有意识到对每一个C风格字符串的比较都有一个malloc的副作用。
由于在程序中和Latin-1编码的C字符串的比较非常常见。Qt提供了一个握有Latin-1编码C字符串指针的被称作 QLatin1String 的特殊的类。除此之外,QString 提供了重载的 QString::operator==(const QLatin1String &) 来调用比较Unicode字符串和Latin1字符串的特殊函数。我们通过写成下面这样可以使上面的代码确定无疑地很快(即无论是是否设置了setCodecForCString),
if (fruit== QLatin1String("apple")) { ... } // fast and mentions encoding
在Qt自身代码中,所有的C字符串的比较都使用了QLatin1String,这是因为应用程序可以为C字符串选择任意编码。
QStringRef:没有 malloc 的字符串操作
QString 为字符串操作提供了各种成员比如mid()、left()、right()。它们都创建会一个新的字符串,因此有一个对在已存在QString的malloc和深拷贝。 与此相反,QString::midRef()、QString::leftRef()与QString::rightRef()可以用来获取一个QStringRef。QStringRef 是对QString一部分的一个引用。为了优化,QString 也提供了许多重载比如 QString::operator==(const QStringRef &) 来配合QStringRef。
QString::reserve 与 QString::squeeze
最好提前调用 QString::reserve 来分配额外的内存,这样每次调用 QString::append() 不会导致一个 malloc。额外的内存可以使用 QString::squeeze 来回收。
QStringBuilder:字符串的快速连接
下面的代码需要至少两次 malloc。第一次molloc用来存放 "(" + type 的结果。然后另一个malloc用来追加 ")"。随着操作符"+"的增加molloc的书目相应增加。
if (foo.startsWith("(" + type + ")"))
如果最终字符串的长度提前已知的话,额外的malloc就可以避免。Qt 4.6 引入了一个为单次调用的连接链(concatenation chain)预留内存的名为 QStringBuilder 的内部类。它通过为上面的每个+操作返回一个不同的类(不再是QString)来实现这一点。该类跟踪被追加的每个字符串和每一步需要的内存。在最后一步,当连接操作被转换成一个QString时它将分配一次内存并将所有字符串依次拷贝进来。该特性可以通过QT_USE_FAST_CONCATENATION来启用。有了这个定义,我们可以使用操作符 "%" 而不是 "+"。现在可以这样写,
if (foo.startsWith("(" % type % ")"))
通过定义 QT_USE_FAST_OPERATOR_PLUS, '+' 而不是 '%' 可以被使用。更多细节详见 快速连接
QStringMatcher:字符串快速匹配
QStringMatcher 可被用来在许多字符串中迭代查找一个字符串或者在同一个字符串中查找多次。它使用 Boyer-Moore 字符串搜索算法 来实现快速搜索。
http://blog.csdn.net/dbzhang800/article/details/6567197
QtInternal 之 高效使用QString(使用QLatin1String,QStringRef,QStringBuilder,QStringMatcher等相关类)的更多相关文章
- QtInternal 之 高效使用QString
注意:本文翻译自 http://developer.qt.nokia.com 中的 UsingQStringEffectively ,中文译文见 简体中文版 ,如果你对翻译wiki感兴趣 ...
- 封装QtCore(在非Qt项目里使用QString,QJson,QFileInfo,QFile等类)
单独封装QtCore 一直以来使用QT的特性使用惯了,很多东西QT都封装得很好.如果突然有一天,不使用QT开发了,是不是不习惯. 比如我们经常使用QString很多方法,string,wstring之 ...
- QString::QString 中文乱码
QString::QString 中文乱码 处理方法: 1. QString str = QString::fromLocal8Bit("中文"); // vs2008 vs200 ...
- Qt隐式共享机制
1.浅拷贝 浅拷贝-引用类型.浅拷贝是指源对象与拷贝对象共用一份实体,仅仅是引用的变量不同(名称不同),对其中任何一个对象的改动都会影响另外一个对象. 2.深拷贝 而深拷贝-值类型.深拷贝是指源对象与 ...
- QString 乱谈(1)
一个月前尝试写了一篇关于QStringLiteral,存盘时MoinMoin罢工了.吸取一点经验,还是写成短篇吧 可是,可是,QString不就是简简单单一个字符串么?能有什么可谈的.真的么... ( ...
- QString介绍
QString stores a string of 16-bit QChars, where each QChar corresponds one Unicode 4.0 character. 一. ...
- QT字符串高效拼接原理QStringBuilder
这一篇文章讨论QT框架中QT字符串是如何实现高效拼接的. 1. QStringBuilder实例与原理 QT字符串高效拼接例子 备注: (a)上述代码仅仅在s2 = b1时一次性分配能够容纳所有字符串 ...
- 关于QStringRef
QString 为字符串操作提供了各种成员比如mid().left().right().它们都创建会一个新的字符串,因此有一个对在已存在QString的malloc和深拷贝. 与此相反,QStri ...
- Qt下 QString转char*
Qt下面,字符串都用QString,确实给开发者提供了方便.Qt再使用第三方开源库时,由于库的类型基本上都是标准的类型,字符串遇的多的就是Char*类型 Qt再使用第三方开源库时,由于库的类型基本上都 ...
随机推荐
- 第七届河南省赛F.Turing equation(模拟)
10399: F.Turing equation Time Limit: 1 Sec Memory Limit: 128 MB Submit: 151 Solved: 84 [Submit][St ...
- Dropping Balls (二叉树+思维)
Dropping Balls A number of K balls are dropped one by one from the root of a fully binary tree st ...
- fastDFS同步问题讨论
一.文件同步延迟问题 前面也讲过fastDFS同组内storage server数据是同步的, Storage server中由专门的线程根据binlog进行文件同步.为了最大程度地避免相互影响以及出 ...
- android技术牛人的博客[转]
Android+JNI调用–文件操作 开发环境:Windows xp sp3 +MyEclipse 8.6+android2.3.3+jdk1.6+android-ndk-r6b JNI概述: ...
- 【HDU】病毒侵袭持续中(AC自己主动机+map)
一開始一直WA,之后发现这道题不止一组输入,改成多组输入之后就过了. 利用map把每一个字符串映射到它相应的结点上即可了. 11909467 2014-10-19 11:54:00 Accepted ...
- XMLHttpRequest对象的使用
1.首先要创建XMLHttpRequest对象,这个对象是前台与后台进行异步的重要对象,现在的浏览器有很多种,创建 XMLHttpRequest 的方法也不相同,所以为了兼容各种浏览器,在创建XMLH ...
- FMDB 直接将查询结果转化为字典
今天学习FMDB框架,发现非常好用的一点,就是就以把查询结果直接转化为字典 NSString *querySql = @"select * from stuInfo"; NSMut ...
- 转 c#代码访问https服务器以及https的webservice
最近公司做到WebService项目,但是要通过Https调用,自己在网上搜了半天,终于实现了服务端的Https,但是一直没有找到客户端如何实现,今天终于看到这篇文章,随手记录下来. 具体代码如下: ...
- 内置的材质包含文件 .cginc
Unity中包含几个文件,可以用于你的Shader程序,里面包含了预定义的变量和辅助函数.使用它需要用 #include指令 CGPROGRAM // ... #include "Unity ...
- union 和 union all 有什么不同?
假设我们有一个表 Student, 包括以下字段与数据:drop table student;create table student( idint primary key,name nvarchar ...