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中一样.)
我用 -O2 处的 clang (特别是Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn))尝试了这个。
来源:
\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}\nRun 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\nRun 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\nRun Code Online (Sandbox Code Playgroud)\n\n鉴于此,我不会太担心这样做的额外开销。
\n| 归档时间: |
|
| 查看次数: |
191 次 |
| 最近记录: |