首页 > 解决方案 > 在 Qt 中设置 pixmap 时的奇怪执行时间

问题描述

看看下面的代码,Image是QImage类型的类成员。

void ImageViewer::setImage(const QImage &newImage)
{
Image = newImage; // takes 108 milliseconds
imageLabel->setPixmap(QPixmap::fromImage(Image)); // takes 58 milliseconds
}

因为我不再需要将newImage设置为Image类成员,所以我只需使用newImage的引用并节省时间。但我很惊讶。

void ImageViewer::setImage(const QImage &newImage)
{
imageLabel->setPixmap(QPixmap::fromImage(newImage)); // takes 158 milliseconds
}

它需要同样的时间。我在这里想念什么?

编辑对于那些想知道我如何测量时间的人,我使用了这里建议的 QElapsedTimer

图像每次都相同,代码是自定义滚动的一部分。您必须知道每次进入此函数时都会加载大小为 2380x3368 的相同图像(.jpg)。每次评论中的时间都是平均时间,测量的时间几乎相同。

但个人认为图像格式或大小不是这里的主要问题。主要问题应该是为什么当我使用 ref 到现有 QImage 时 SetPixmap 比创建一个新的 QImage 然后发送到这个函数需要更多的时间。这没有任何意义。

标签: c++qt

解决方案


来自文档:http ://doc.qt.io/qt-5/qimage.html#operator-eq

QImage &QImage::operator=(const QImage &image)将给定图像的拷贝分配给该图像并返回对该图像的引用。

因此,我们可以确定您的两个代码块实际上是等效的,因为制作图像的写时复制副本基本上是免费操作(在查看毫秒时间尺度时)。

在您的第一个示例中,看起来很多时间都花在了初始副本上,这一事实可能是您如何对代码进行基准测试的人为因素。

编辑Copy-on-write 意味着两者在分配ImagenewImage共享底层数据,并在其中一个第一次发散时按需制作数据副本。实际上,它并不比复制指针贵多少。


推荐阅读