c++ - GCC 是否优化 std::tie 仅用于可读性?

标签 c++ c++11 optimization tuples tie

假设我有一个 std::tuple :

std::tuple<int,int,int,int> t = {1,2,3,4};

我想使用 std::tie只是为了这样的可读性目的:

int a, b, c, d; // in real context these names would be meaningful
std::tie(a, b, c, d) = t;

对比只使用 t.get<int>(0)

GCC 会优化这个元组的内存使用还是会为 a, b, c, d 分配额外的空间?变量?

最佳答案

在这种情况下,我看不出有任何理由不这样做,在 as-if rule 下编译器只需要模拟程序的可观察行为。快速实验 using godbolt :

#include <tuple>
#include <cstdio>

void func( int x1, int x2,int  x3, int x4)
{
  std::tuple<int,int,int,int> t{x1,x2,x3,x4};

  int a, b, c, d; // in real context these names would be meaningful
  std::tie(a, b, c, d) = t;

  printf( "%d %d %d %d\n", a, b, c, d ) ;
}

表明 gcc 确实优化了它:

func(int, int, int, int):
    movl    %ecx, %r8d
    xorl    %eax, %eax
    movl    %edx, %ecx
    movl    %esi, %edx
    movl    %edi, %esi
    movl    $.LC0, %edi
    jmp printf

另一方面,如果您使用地址 t 并将其打印出来,我们现在可以观察到依赖于 t 现有的行为 ( see it live ):

printf( "%p\n", static_cast<void*>(&t) );

我们可以看到 gcc 不再优化 t:

movl    %esi, 12(%rsp)
leaq    16(%rsp), %rsi
movd    12(%rsp), %xmm1
movl    %edi, 12(%rsp)
movl    $.LC0, %edi
movd    12(%rsp), %xmm2
movl    %ecx, 12(%rsp)
movd    12(%rsp), %xmm0
movl    %edx, 12(%rsp)
movd    12(%rsp), %xmm3
punpckldq   %xmm2, %xmm1
punpckldq   %xmm3, %xmm0
punpcklqdq  %xmm1, %xmm0

归根结底,您需要查看编译器生成的内容并分析您的代码,在更复杂的情况下,这可能会让您大吃一惊。仅仅因为允许编译器进行某些优化并不意味着它会。我看过更复杂的情况,在这些情况下,编译器没有按照我对 std::tuple 的预期进行操作。 godbolt 在这里是一个非常有用的工具,我无法计算我过去有多少优化假设是通过将简单的示例插入到 godbolt 中而被覆盖的。

请注意,我通常在这些示例中使用 printf,因为 iostreams 会生成大量妨碍示例运行的代码。

关于c++ - GCC 是否优化 std::tie 仅用于可读性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30212307/

相关文章:

c++ - 为什么这个 c++ 程序不处理异常并为负数提供核心转储

c++ - Gstreamer Textoverlay 未更新

c++ - 序列化哪里出错了?

c++ - 将 std::conditional 与迭代器一起使用

c++ - UpdateByValue 函数什么也没做?

c++ - 怎么会?特征中未检测到别名

c++ - 使用模板可变参数函数将多个参数传递给另一个函数

javascript - 精简 jQuery

mysql - 在 Varchar 上创建 MySQL 索引总是会产生 2 个索引?

language-agnostic - 尽早规划效率与过早优化