qt 5中qlist
Posted 马肯尼煤牙巴骨
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了qt 5中qlist相关的知识,希望对你有一定的参考价值。
源起
最近在写modbus 封装
modbus中,数据类型只有bool 和 int16
发送float时,需要把float拆成多个int16
接收float时,需要把多个int16拼接成float
写单元测试时,刚开始使用了qlist
代码是这样的
template<class T> constexpr inline static T getModbusReadedResult(QVector<quint16> star,bool isBigEndian = false)
int i = 1;
char* b = (char*)&i;
bool needCvt = !*b ^ isBigEndian; //不一致需要转换
//QVector<quint16> bytes = lst.toVector();
T ret;
if constexpr (sizeof(T) ==8)
//uint64_t* lstBytes = (uint64_t*) bytes.data();
uint64_t* bytes = (uint64_t*) star.data(); //bytes = qvector数组地址时正常,如果是qlist时会崩溃
if (needCvt)
(*(uint64_t*)&ret) =
(*bytes & 0x00000000000000ff) <<56|
(*bytes & 0x000000000000ff00) <<40|
(*bytes & 0x0000000000ff0000) <<24|
(*bytes & 0x00000000ff000000) <<8 |
(*bytes & 0x000000ff00000000) >>8 |
(*bytes & 0x0000ff0000000000) >>24|
(*bytes & 0x00ff000000000000) >>40|
(*bytes & 0xff00000000000000) >>56;
... 略
换成vector后好了
于是打算研究一下qlist这个东西
qt 5的qvector 和标准库的vector基本上拥有相同的内存布局和行为,api可能不同,但数据结构一样,所以这里直接pass
qlist 的基本特性 及结构
qt 5 的qlist 是一个折衷的东西
相对于stl的list,它有下标访问的能力,内存在大多数情况下都是连继的
甚至基于下标访问时间复杂度和qvector大多数情况下是一样的 (一开始我以为是像stl dequeue那样局部连续
相对于stl的vector,它不仅能下标访问,也能快速的插入,但它不是链表结构,所以这个快速插入,其实也不是很快,但大多数情况下,比vector快
因为,qlist的结构是大致可以认为是这样
预留空间
+ void* 数组
+ 预留空间
qlist插入性能
相对于qvector, 它的不仅后面会预先申请内存,前面也会有,这使得它在前面插入 和最后面插入时,时间复杂度都是O(1),空间不足时O(n)
中间插入时,时间复杂度是O(n),但因为它都是void* 所以 O(n) 通常来说会比qvector更快,
如果qvector里放的是指针中间插入的速度它俩一样
如果qvector里放的是小于指针的值,那vector中间插入的速度更快
不过,通常来说,qvector里放的都不是以上两种,所以通常来说qlist中间插入性能会比qvector好,
插入前面的速度 qvector为O(n)弱于qlist
插入后面的速度,两者相当O(1) ,或重分配空间O(n)
qlist 的 两种行为
当 sizeof(T) > sizeof(void)时,或者qlist不认识的类型时, T会被new 在heap, 把指针存在qlist的数组空间中
当 sizeof(T) <= sizeof(void)时 ,不会把对象new在堆上,而是直接存放在 qlist的数组空间中
为什么我的单元测试使用qlist时会崩溃
因为modbus所需要的数据是 qint16, sizeof(qunit16) 小于sizeof(void), 但qlist的数组空间每一个元素的空间是固定的sizeof(void)
所以有间隙,不再是连续的
于是当我把它当成连续的地址来用时,崩溃了
结论
在qt 5中,qvector应该是首选的容器,如果不需要播放性能的话
慎用qlist, 对于某一些类型,qlist 在32位系统和64位系统中行为不一样
再者,不管是qlist还是qvector,在qt6中都有较大改动,如果要迁移到qt 6,需要注意 旧程序的qvector 可以简单的替换为std::vector ,保证其兼容性
qlist的话,没有类似的东西可以兼顾它的各方面特性, 需要根据使用情景调整选用容器
[QT]加快qt编译:设置默认多核编译qt
使用环境:win7 + QT Creator 4.2.1 + QT5.8 + MinGW5.3.0 32bit
设置默认多核编译qt 来源:http://stackoverflow.com/questions/8860712/setting-default-make-options-for-qt-creator
单个项目设置多核编译:作者 学海方舟:加快QT工程编译速度:http://blog.csdn.net/favory/article/details/50061141
菜单栏->工具-> 选项->构建与运行->构建套件->点击自动检测内容->在同一页面找到 Environment ->点击change ->在弹出的窗口 添加MAKEFLAGS=-j4 即可
-j4 :表示cup四个核数加入编译
图一
图二
以上是关于qt 5中qlist的主要内容,如果未能解决你的问题,请参考以下文章