int和只包含int的结构之间是否存在性能差异?

Tim*_*Tim 6 c int performance struct

在C中,typedef不会授予您任何其他类型安全性.您可以在任何可以使用旧类型的地方使用新类型.有时这就是我想要的,有时却不是.有时我希望编译器在我滥用新类型时警告我.

为了实现这一点,我有时做这样的事情:

typedef struct {
    int value;
} NewType;

NewType doSomethingNT(NewType a, NewType b) {
    return a.value + b.value;
}
Run Code Online (Sandbox Code Playgroud)

相比:

int doSomethingI(int a, int b) {
    return a + b;
}
Run Code Online (Sandbox Code Playgroud)

(这只是一个例子.让我们假设在两种情况下都有一个函数调用开销,否则我要求函数在两种情况下都内联.但是我们不要将doSomethingNT与bare +运算符进行比较,显然后者更快因为它没有函数调用开销)

我想我问,是否有任何开销在"装箱"原始类型的单元素结构,但使用该结构作为值类型.(即我不是在调用malloc并使用指针,就像拳击在Java中一样.)

Lnx*_*gr3 4

我用 -O2 处的 clang (特别是Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn))尝试了这个。

\n\n

来源:

\n\n
#include <stdio.h>\n\nstruct da_int {\n    short i;\n};\n\nstruct da_int add(struct da_int x, struct da_int y) {\n    struct da_int rv = {x.i + y.i};\n    return rv;\n}\n\nint main(int argc, char *argv[]) {\n    struct da_int x = {5}, y = {3};\n    printf("%d\\n", add(x, y).i);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

编译器稍微挫败了我的计划\xe2\x80\x94生成的 main 从未调用 add,而是在编译时计算结果:

\n\n
_main:                                  ## @main\n    .cfi_startproc\n## BB#0:\n    pushq    %rbp\nLtmp7:\n    .cfi_def_cfa_offset 16\nLtmp8:\n    .cfi_offset %rbp, -16\n    movq    %rsp, %rbp\nLtmp9:\n    .cfi_def_cfa_register %rbp\n    leaq    L_.str(%rip), %rdi\n    movl    $8, %esi\n    xorb    %al, %al\n    callq    _printf\n    xorl    %eax, %eax\n    popq    %rbp\n    ret\n    .cfi_endproc\n
Run Code Online (Sandbox Code Playgroud)\n\n

但它确实生成了一个添加函数!它在寄存器中获取参数并在寄存器中返回结果。包装器结构在编译器输出中完全消失,至少对于这个简单的情况是这样:

\n\n
_add:                                   ## @add\n    .cfi_startproc\n## BB#0:\n    pushq    %rbp\nLtmp2:\n    .cfi_def_cfa_offset 16\nLtmp3:\n    .cfi_offset %rbp, -16\n    movq    %rsp, %rbp\nLtmp4:\n    .cfi_def_cfa_register %rbp\n    addl    %esi, %edi\n    movw    %di, %ax\n    popq    %rbp\n    ret\n    .cfi_endproc\n
Run Code Online (Sandbox Code Playgroud)\n\n

鉴于此,我不会太担心这样做的额外开销。

\n