C++ 在本例中,取消引用指针是否会创建副本?

C++ 在本例中,取消引用指针是否会创建副本?,c++,qt,dereference,qpixmap,C++,Qt,Dereference,Qpixmap,我正在尝试优化一些代码,因为我必须多次在较大的QPixmap上绘制相同的QPixmap。由于在我自己的方法中按值传递QPixmap会在每次调用中创建副本,因此我认为通过使用指向QPixmap的指针可以节省一些时间。然而,我的工作似乎一直在进行中。我认为这是因为调用QPainter::drawPixmap(…,const QPixmap&,…)会创建它的副本 QPixmap *pixmap = new QPixmap(10,10); painter.drawPixmap(0,0, *pixmap)

我正在尝试优化一些代码,因为我必须多次在较大的QPixmap上绘制相同的QPixmap。由于在我自己的方法中按值传递QPixmap会在每次调用中创建副本,因此我认为通过使用指向QPixmap的指针可以节省一些时间。然而,我的工作似乎一直在进行中。我认为这是因为调用QPainter::drawPixmap(…,const QPixmap&,…)会创建它的副本

QPixmap *pixmap = new QPixmap(10,10);
painter.drawPixmap(0,0, *pixmap);
在本例中是否正在创建副本

如果是这样,我该如何优化将多个图像绘制到另一个图像上


我已经在这里读过这个Q/A:但是我想不出我的具体案例的确切答案。

否。
drawPixmap
函数引用了
pixmap
,因此没有复制。以下是QPaint成员函数的原型:

  void  drawPixmap ( int x, int y, const QPixmap & pixmap )

否。函数
drawPixmap
pixmap
进行
const
引用,因此不进行复制。以下是QPaint成员函数的原型:

  void  drawPixmap ( int x, int y, const QPixmap & pixmap )
根据报告:

QPixmap对象可以通过值传递,因为QPixmap类 使用隐式数据共享。有关详细信息,请参见隐式 数据共享文件

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;
    }
}
只有当pixmap处于绘制活动状态时,才需要深度复制,否则新的pixmap只需要复制原始数据指针

对于常量引用和指针的差异:

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);
这两者之间应该没有区别,因为编译器将生成相同的汇编代码:将指针传递给drawPixmap函数

和QDateTime::currentMSecsSinceEpoch()在我的方框上显示的结果几乎相同。

根据:

QPixmap对象可以通过值传递,因为QPixmap类 使用隐式数据共享。有关详细信息,请参见隐式 数据共享文件

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;
    }
}
只有当pixmap处于绘制活动状态时,才需要深度复制,否则新的pixmap只需要复制原始数据指针

对于常量引用和指针的差异:

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);
这两者之间应该没有区别,因为编译器将生成相同的汇编代码:将指针传递给drawPixmap函数


而QDateTime::currentMSecsSinceEpoch()在我的方框上显示的结果几乎相同。

可能不是严格意义上的正确。在他的例子中,他实际上是通过引用传递的,所以这并不重要。如果他按值传递,它肯定会有一些(尽管可能可以忽略不计)比引用传递机制更大的窃听。对。。每100k绘制一次,差异仅为1秒。@Sosukodo:由于您的代码使用引用,所以引用和点之间应该没有性能差异。你是如何得到性能差异的?我是如何计算的?基本上,在对drawPixmap的100k调用之前和之后,QDateTime::currentMSecsSinceEpoch()的增量。谢谢。那是你应得的!可能不是严格意义上的正确。在他的例子中,他实际上是通过引用传递的,所以这并不重要。如果他按值传递,它肯定会有一些(尽管可能可以忽略不计)比引用传递机制更大的窃听。对。。每100k绘制一次,差异仅为1秒。@Sosukodo:由于您的代码使用引用,所以引用和点之间应该没有性能差异。你是如何得到性能差异的?我是如何计算的?基本上,在对drawPixmap的100k调用之前和之后,QDateTime::currentMSecsSinceEpoch()的增量。谢谢。那是你应得的!