我正在尝试优化一些代码,因为我必须多次将相同的QPixmap绘制到更大的代码上。由于在我自己的方法中按值传递QPixmap会在每次调用时创建副本,我想我可以通过使用指向QPixmaps的指针来节省一些时间。然而,似乎我的工作一直在进行。我认为这是因为调用QPainter :: drawPixmap(...,const QPixmap&,...)会创建它的副本。
QPixmap *pixmap = new QPixmap(10,10);
painter.drawPixmap(0,0, *pixmap);
是否在此示例中创建了副本?
如果是这样,我怎样才能优化将许多图像绘制到另一个图像上?
我已经在这里阅读了这个Q / A:Does dereferencing a pointer make a copy of it?但我的具体案例的确切答案使我无法接受。
答案 0 :(得分:4)
没有。函数drawPixmap
对const
采用pixmap
引用,因此不会复制。这是QPainter成员函数的原型:
void drawPixmap ( int x, int y, const QPixmap & pixmap )
答案 1 :(得分:0)
自QPixmap类以来,QPixmap对象可以按值传递 使用隐式数据共享。有关更多信息,请参阅Implicit 数据共享文档。
QPixmap实施:
QPixmap::QPixmap(const QPixmap &pixmap)
: QPaintDevice()
{
if (!qt_pixmap_thread_test()) {
init(0, 0, QPixmapData::PixmapType);
return;
}
if (pixmap.paintingActive()) { // make a deep copy
operator=(pixmap.copy());
} else {
data = pixmap.data;
}
}
只有当像素图画面处于活动状态时,您才需要深度复制,否则新的像素图只需要复制原始数据指针。
对于const引用和指针的区别:
QPixmap largeMap(1000, 1000);
QPainter p(&largeMap);
int count = 100000;
qint64 time1, time2;
QPixmap *pSmallMap = new QPixmap("e:/test.png");
QPixmap smallMap = QPixmap("e:/test.png");
time1 = QDateTime::currentMSecsSinceEpoch();
for (int i = 0; i < count; ++i) {
p.drawPixmap(0, 0, *pSmallMap);
}
time2 = QDateTime::currentMSecsSinceEpoch();;
qDebug("def time = %d\n", time2 - time1);
time1 = QDateTime::currentMSecsSinceEpoch();
for (int i = 0; i < count; ++i) {
p.drawPixmap(0, 0, smallMap);
}
time2 = QDateTime::currentMSecsSinceEpoch();;
qDebug("normal time = %d\n", time2 - time1);
在Visual Studio 2010下编译调试配置将产生以下程序集:
28: p.drawPixmap(0, 0, *pSmallMap);
003B1647 8B 55 C4 mov edx,dword ptr [ebp-3Ch] //the pixmap pointer
003B164A 52 push edx
003B164B 6A 00 push 0 //x
003B164D 6A 00 push 0 //y
003B164F 8D 4D F0 lea ecx,[ebp-10h] //the qpainter pointer
003B1652 FF 15 9C D7 3B 00 call dword ptr [__imp_QPainter::drawPixmap (3BD79Ch)]
35: p.drawPixmap(0, 0, smallMap);
003B16A8 8D 4D E0 lea ecx,[ebp-20h] //the pixmap pointer
003B16AB 51 push ecx
003B16AC 6A 00 push 0 //x
003B16AE 6A 00 push 0 //y
003B16B0 8D 4D F0 lea ecx,[ebp-10h] //the qpainter pointer
003B16B3 FF 15 9C D7 3B 00 call dword ptr [__imp_QPainter::drawPixmap (3BD79Ch)]
这两者之间应该没有区别,因为编译器会生成相同的汇编代码:将指针传递给drawPixmap函数。
QDateTime :: currentMSecsSinceEpoch()几乎在我的盒子上显示相同的结果。