gpt4 book ai didi

c++ - postfix++/-- 运算符的低效率是否会针对 STL 迭代器进行优化?

转载 作者:可可西里 更新时间:2023-11-01 15:20:44 26 4
gpt4 key购买 nike

我知道自增/自减运算符的后缀版本通常会由编译器针对内置类型进行优化(即不会进行复制),但 iterator 是否属于这种情况是吗?

它们本质上只是重载运算符,可以通过多种方式实现,但由于它们的行为是严格定义的,能否优化它们,如果可以,它们是否被任何/许多人优化编译器?

#include <vector> 

void foo(std::vector<int>& v){
for (std::vector<int>::iterator i = v.begin();
i!=v.end();
i++){ //will this get optimised by the compiler?
*i += 20;
}
}

最佳答案

std::vector 的特定情况下在 GNU GCC 的 STL 实现(版本 4.6.1)上,我认为在足够高的优化级别上不会有性能差异。

前向迭代器在 vector 上的实现由 __gnu_cxx::__normal_iterator<typename _Iterator, typename _Container> 提供.我们看一下它的构造函数和后缀 ++运算符(operator):

  explicit
__normal_iterator(const _Iterator& __i) : _M_current(__i) { }

__normal_iterator
operator++(int)
{ return __normal_iterator(_M_current++); }

及其在vector中的实例化:

  typedef __gnu_cxx::__normal_iterator<pointer, vector> iterator;

如您所见,它在内部对普通指针执行后缀递增,然后通过其自己的构造函数传递原始值,并将其保存到本地成员。这段代码应该很简单,可以通过死值分析来消除。

但它真的优化了吗?让我们找出来。测试代码:

#include <vector>

void test_prefix(std::vector<int>::iterator &it)
{
++it;
}

void test_postfix(std::vector<int>::iterator &it)
{
it++;
}

输出组件(在 -Os 上):

    .file   "test.cpp"
.text
.globl _Z11test_prefixRN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE
.type _Z11test_prefixRN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE, @function
_Z11test_prefixRN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE:
.LFB442:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
movl 8(%ebp), %eax
addl $4, (%eax)
popl %ebp
.cfi_def_cfa 4, 4
.cfi_restore 5
ret
.cfi_endproc
.LFE442:
.size _Z11test_prefixRN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE, .-_Z11test_prefixRN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE
.globl _Z12test_postfixRN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE
.type _Z12test_postfixRN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE, @function
_Z12test_postfixRN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE:
.LFB443:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
movl 8(%ebp), %eax
addl $4, (%eax)
popl %ebp
.cfi_def_cfa 4, 4
.cfi_restore 5
ret
.cfi_endproc
.LFE443:
.size _Z12test_postfixRN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE, .-_Z12test_postfixRN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE
.ident "GCC: (Debian 4.6.0-10) 4.6.1 20110526 (prerelease)"
.section .note.GNU-stack,"",@progbits

如您所见,两种情况下输出的程序集完全相同。

当然,自定义迭代器或更复杂的数据类型可能不一定如此。但看起来,对于 vector具体来说,前缀和后缀(不捕获后缀返回值)具有相同的性能。

关于c++ - postfix++/-- 运算符的低效率是否会针对 STL 迭代器进行优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6419599/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com