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

时间:2014-03-06 19:07:29

标签: c performance struct int

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

为了实现这一目标,我有时会这样做:

typedef struct {
    int value;
} NewType;

NewType doSomethingNT(NewType a, NewType b) {
    return a.value + b.value;
}

与:相比:

int doSomethingI(int a, int b) {
    return a + b;
}

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

我想我在问,“拳击”原始类型是一个元素结构有没有任何开销,但是使用该结构作为值类型。 (即我不是在调用malloc并使用指针,就像拳击在Java中一样。)

1 个答案:

答案 0 :(得分:4)

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

来源:

#include <stdio.h>

struct da_int {
    short i;
};

struct da_int add(struct da_int x, struct da_int y) {
    struct da_int rv = {x.i + y.i};
    return rv;
}

int main(int argc, char *argv[]) {
    struct da_int x = {5}, y = {3};
    printf("%d\n", add(x, y).i);
}

编译器略微挫败了我的计划 - 生成的main从不调用add,而是在编译时计算结果:

_main:                                  ## @main
    .cfi_startproc
## BB#0:
    pushq    %rbp
Ltmp7:
    .cfi_def_cfa_offset 16
Ltmp8:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp9:
    .cfi_def_cfa_register %rbp
    leaq    L_.str(%rip), %rdi
    movl    $8, %esi
    xorb    %al, %al
    callq    _printf
    xorl    %eax, %eax
    popq    %rbp
    ret
    .cfi_endproc

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

_add:                                   ## @add
    .cfi_startproc
## BB#0:
    pushq    %rbp
Ltmp2:
    .cfi_def_cfa_offset 16
Ltmp3:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp4:
    .cfi_def_cfa_register %rbp
    addl    %esi, %edi
    movw    %di, %ax
    popq    %rbp
    ret
    .cfi_endproc

鉴于此,我不会过分担心这样做带来的额外开销。