2008-11-07 62 views
1

该主题一般性地说明了一切。基本上在这样的情况:boost :: scoped_array中&p [0]与p.get()的性能影响

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

是否有这样做之间的性能有任何明显的差异:&p[0]p.get()

我问,因为我更喜欢第一个,它有一个更自然的指针,像语法。事实上,它使得它可以用一个本地指针或数组替换p,而不必改变其他任何东西。

我在猜测,因为get是一个单行的“return ptr;”,编译器会内联该函数,我希望它足够聪明以便能够以不能解引用并立即引用的方式内联operator[]

有人知道吗?

回答

1

好的,我按照约克的建议做了一些基本的测试。

看来,g ++(4.3.2)其实是相当不错的。在-O2和-O3两种优化级别下,它都会输出略微不同但功能相同的组件,用于&p[0]p.get()

在-Os如预期的那样,它采取了最复杂的路径并发出呼叫operator[]。有一点要注意的是,&p[0]版本确实会导致G ++发出的operator[]身体的副本,但从来没有使用过,所以有轻微的代码膨胀,如果你从来没有使用operator[]否则:

测试的代码是这样的(与#if 0和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 
} 
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。

+0

我看过源码,运算符[]基本上只是做了一个“return ptr [i];” (有一些断言,但这是重要的代码)。我的问题是,在使用operator []函数的情况下,编译器是否足够聪明才能知道&ptr [0] == ptr。 – 2008-11-07 22:50:03

+0

你在问编译器是否足够聪明以优化'ptr + 0'。检查你的编译器的输出。 – 2008-11-07 22:53:25

+0

嘿,你可以说“我不知道”:-P。无论如何,我知道如果p是一个本地指针,它可以。我想如果运算符[]的参数在编译时是已知的,它*应该*能够将它全部归因于它。我想知道它是否。 – 2008-11-07 22:58:27

0

这是你的要求只是为了学术兴趣问题或这是为你写一些当前的代码?

一般来说,人们建议代码清晰度对于速度来说更重要,所以除非您确定这会有所作为,否则您应该选择更清晰的选项并与您的代码库相匹配。 FWIW,我个人认为get()更清晰。