【发布时间】:2014-09-01 18:42:41
【问题描述】:
我正在研究 Kruse、Leung 和 Tondo 的“C 中的数据结构和程序设计”。第 2 章第 2 节介绍了一个简单的数据结构(列表),稍后要求读者为该结构编写两个不同的复制函数。有问题的练习是 E2,内容如下:
编写将一个列表复制到另一个列表的函数(作为文本中定义的结构类型)。使用以下方法: (a) 复制整个结构; (b) 使用循环仅复制条目。哪个版本更容易写?哪个版本通常会运行得更快,为什么?
我的问题出现在本练习的最后一部分:“哪个版本通常运行得更快,为什么?”。我知道复制整个结构更快,我的理解表明这是因为可以避免循环的开销。但是,当我运行每个条目时,我惊讶地发现复制整个结构不仅比复制每个条目要快,而且大约快 10 倍。
我希望有人能够向我解释为什么会这样,或者至少将我引导到可以帮助我理解的来源。我试着通读了我写的两个函数的汇编,但是我对汇编的理解在这一点上是非常基础的。
谢谢!
相关代码:
#define MAXLIST 200 //maximum size of lists
extern void Error(const char *);
typedef struct coord_tag {
int row; //x
int col; //y
} Coord_type;
typedef Coord_type Entry_type;
typedef struct list_tag {
int count;
Entry_type entry[MAXLIST];
} List_type;
void Copy(List_type *lt, List_type *lf) //list "to" and list "from"
{
if (lt == NULL || lf == NULL) {
Error("list uninitialized");
} else {
*lt = *lf;
}
}
void Copy2(List_type *lt, List_type *lf)
{
if (lt == NULL || lf == NULL) {
Error("list uninitialized");
} else {
int i;
lt->count = lf->count;
for (i = 0; i < lf->count; i++) {
lt->entry[i] = lf->entry[i];
}
}
}
【问题讨论】:
-
查看生成的程序集。
-
如果你想帮助理解程序集,你应该发布它;)
-
这是如何编译的?
-
试试和memcpy比较一下,第一个副本相当于memcpy。有for循环的时候编译器可能不知道那些入口肯定在一个连续的内存位置,必须经过for循环,但是有汇编指令可以整块内存拷贝。
-
两个建议:1. 使用不同级别的优化重新运行您的测试(在非 Windows 系统上,这通常通过
-O1、-O2、-O3或-Os选项实现)。 2. 要更深入地了解幕后发生的事情,请将Copy2()放入它自己的源文件中,并使用编译器标志-Os -S进行编译。这将为您提供一个文件扩展名为“.s”的文件,其中包含汇编代码。优化标志不是绝对必要的,但根据我的经验,它可以显着提高汇编代码的可读性。
标签: c optimization data-structures