我有自己的模拟堆块的数据结构。
typedef struct heap_block
{
struct heap_block* next;
size_t size;
bool isfree;
} header;
我有一个迭代我的数据结构的方法(它就像一个列表):
void craw(header* crawler, bool isfree, int* counter)
{
while(crawler->next != NULL)
{
if(crawler->isfree == isfree)
{
++(*counter);
}
crawler = crawler->next;
}
if(crawler->isfree == isfree)
{
++(*counter);
}
}
我需要使用额外的检查,因为最后一个元素有crawler->next == NULL
如何改进此迭代?
答案 0 :(得分:2)
您可能希望将循环测试更改为while (crawler != NULL) { ... }
,如下所示:
void craw(header* crawler, bool isfree, int* counter)
{
while(crawler != NULL)
{
if(crawler->isfree == isfree)
{
++(*counter);
}
crawler = crawler->next;
}
}
此更改还可以防止在使用craw()
抓取工具调用NULL
时代码崩溃。
答案 1 :(得分:2)
这可能是您可以迭代链表的最简洁方法。
void craw(header* crawler, bool isfree, int* counter)
{
for (; crawler; crawler = crawler->next)
{
if (crawler->isFree == isFree)
++(*counter);
}
}
答案 2 :(得分:2)
我正在寻找性能改进,但如果没有实际分析发布版本中的代码,很难说。优化器可以做你从未梦想过的事情。也就是说,你可以做的一件事就是在每次迭代时都不要取消引用计数器。没有任何内容表明它的内存将与其余的derefrenced列表数据一起被分页,因此在每次迭代时取消引用它可能会带来昂贵的提取。相反,在迭代开始之前分配一个本地计数器,在每次迭代时增加它,并在返回之前分配解除引用的计数器参数。
void craw(header* crawler, bool isfree, int* counter)
{
int local_counter = *counter; // assuming counter != 0
... iterate ...
local_counter++;
*counter = local_counter;
}
答案 3 :(得分:2)
如果结果可以通过返回值返回,则无需按引用进行调用。因此,您可以将函数更改为 true 函数,而不是void " procedure" :
unsigned crawl2(header *crawler, bool isfree)
{
unsigned count;
for (count =0; crawler; crawler=crawler->next)
{
if (crawler->isFree != isFree) continue;
count++;
}
return count;
}
注意:如果内联函数,事情可能会有所不同。在这种情况下,*计数器的引用可以解析为直接的(并且它甚至可以在循环期间保存在寄存器中)