在C语言中把一个结构赋值给另一个结构
假设我有两个结构s1和s2,每个结构包含10000个元素的数组。如果我将一个结构复制到另一个结构,比如s1=s2,然后通过循环从1复制到10000,然后s1[I]=s2[I]。这两种方法之间会有速度差异吗?如果是,请告诉我哪一个更快,为什么?我认为编译器为表达式s1=s2生成的代码比显式使用用户定义的循环要快。编译器很可能会使用标准C函数memcpy执行摘要: 在我的编译器上,所有这些都转换为对memcpy类函数的调用。它们恰好不同,但编译器或多或少地认识到所有这些实现在功能上都是相同的 这些不同的memcpy实现之间的性能差异可能很小 代码: 编译器信息在C语言中把一个结构赋值给另一个结构,c,C,假设我有两个结构s1和s2,每个结构包含10000个元素的数组。如果我将一个结构复制到另一个结构,比如s1=s2,然后通过循环从1复制到10000,然后s1[I]=s2[I]。这两种方法之间会有速度差异吗?如果是,请告诉我哪一个更快,为什么?我认为编译器为表达式s1=s2生成的代码比显式使用用户定义的循环要快。编译器很可能会使用标准C函数memcpy执行摘要: 在我的编译器上,所有这些都转换为对memcpy类函数的调用。它们恰好不同,但编译器或多或少地认识到所有这些实现在功能上都是相同的 这些不
你喜欢困难吗?如果是,则使用第二种方法。不要忘记索引0处的元素@pmg:。。。忘了索引为10000的那个!它可能不完全使用标准memcpy,但可能使用一些特定于实现的变体,例如GCC中的u builtin memcpy,它有时也可以用于标准memcpy。。。这可能是因为自分配是合法的,但使用memcpy自复制是非法的。回到任务使用memcpy的那一天,一些分析工具对memcpy的重叠进行了误报。
#include <stdlib.h>
#include <string.h>
struct S {
int x[10000];
};
void impl1(struct S *x, struct S *y) __attribute__((noinline));
void impl1(struct S *x, struct S *y) {
*x = *y;
}
void impl2(struct S *x, struct S *y) __attribute__((noinline));
void impl2(struct S *x, struct S *y) {
memcpy(x, y, sizeof(*x));
}
void impl3(struct S * restrict x, struct S * restrict y) __attribute__((noinline));
void impl3(struct S * restrict x, struct S * restrict y) {
for (int i=0; i<10000; ++i)
x->x[i] = y->x[i];
}
int main() {
struct S x, y;
impl1(&x, &y);
impl2(&x, &y);
impl3(&x, &y);
}
define void @impl1(%struct.S* nocapture %x, %struct.S* nocapture readonly %y) #0 {
%1 = bitcast %struct.S* %x to i8*
%2 = bitcast %struct.S* %y to i8*
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* %2, i64 40000, i32 4, i1 false), !tbaa.struct !1
ret void
}
define void @impl2(%struct.S* %x, %struct.S* %y) #0 {
%1 = bitcast %struct.S* %x to i8*
%2 = bitcast %struct.S* %y to i8*
%3 = tail call i64 @llvm.objectsize.i64.p0i8(i8* %1, i1 false)
%4 = tail call i8* @__memcpy_chk(i8* %1, i8* %2, i64 40000, i64 %3) #1
ret void
}
define void @impl3(%struct.S* noalias nocapture %x, %struct.S* noalias nocapture readonly %y) #0 {
%x2 = bitcast %struct.S* %x to i8*
%y3 = bitcast %struct.S* %y to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %x2, i8* %y3, i64 40000, i32 4, i1 false)
ret void
}
[10:04am][wlynch@watermelon /tmp] clang -v
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.3.0
Thread model: posix