1

该主题通常说明了一切。基本上是这样的情况:

boost::scoped_array<int> p(new int[10]);

在做:&p[0]和之间的性能上有什么明显的区别p.get()吗?

我问是因为我更喜欢第一个,它有一个更自然的指针,如语法。事实上,它使您可以用本机指针或数组替换 p 而不必更改任何其他内容。

我猜因为 get 是一个单行“ return ptr;”,编译器将内联它,我希望它足够聪明,能够以operator[]这样一种方式内联,即它能够不取消引用然后立即引用。

有人知道吗?

4

3 回答 3

2

唯一知道的方法就是实际测量它!

但是,如果您有 boost:scoped_array 的来源,您可以查看代码并查看它的作用。我确信它非常相似。

T * scoped_array::get() const // never throws
{
    return ptr;
}

T & scoped_array::operator[](std::ptrdiff_t i) const // never throws
{
    BOOST_ASSERT(ptr != 0);
    BOOST_ASSERT(i >= 0);
    return ptr[i];
}

编写两个版本的代码(一个使用 get(),另一个使用 operator[])。在打开优化的情况下编译为汇编。看看你的编译器是否真的设法优化掉 ptr+0。

于 2008-11-07T22:48:25.890 回答
1

好的,我已经按照 Martin York 的建议进行了一些基本测试。

似乎 g++ (4.3.2) 在这方面实际上相当不错。在 -O2 和 -O3 优化级别,它为&p[0]和输出略有不同但功能相同的程序集p.get()

正如预期的那样,在 -Os 处,它采用了复杂性最低的路径并发出对operator[]. 需要注意的一点是,该&p[0]版本确实会导致 g++ 发出operator[]主体的副本,但它从未使用过,因此如果您从不使用operator[]其他方式,则会出现轻微的代码膨胀:

测试的代码是这样的(#if0和1):

#include <boost/scoped_array.hpp>
#include <cstdio>

int main() {
    boost::scoped_array<int> p(new int[10]);
#if 1
    printf("%p\n", &p[0]);
#else
    printf("%p\n", p.get());
#endif
}
于 2008-11-07T23:07:29.457 回答
0

这是您只是出于学术兴趣而提出的问题,还是您正在编写的一些当前代码?

通常,人们建议代码清晰比速度更重要,因此除非您确定这会有所作为,否则您应该选择更清晰且与您的代码库匹配的选项。FWIW,我个人认为 get() 更清晰。

于 2008-11-08T02:24:37.060 回答