【发布时间】:2021-02-16 01:03:12
【问题描述】:
例如,假设您有一个链表 1->2->3->4->5->6->NULL 并且您想要计算该链表的偶数索引的总和(假设第一个index从1开始,链表大小为偶数)
第一种方法
int total = 0;
int count = 0;
Node *ptr = head;
while(ptr != NULL)
{
if(count % 2 == 0)
{
total += ptr->data;
}
count++;
ptr = ptr->next;
}
第二种方法
int total = 0;
Node *ptr = head;
while(ptr != NULL)
{
total += ptr->data;
ptr = ptr->next->next;
}
那么在我做了这两种方法之后,它们的性能是否相同?
【问题讨论】:
-
如果有奇数个节点,第二种方法很容易出现未定义的行为。
-
测量它,但请注意,如果不是本示例之外的内容,遍历整个链表可能会大大超过差异。
-
如果您测量创建 10,000 个节点,然后使用 std::chrono 对两种算法进行计时。确保您使用的是优化/发布版本。时序相关:https://en.cppreference.com/w/cpp/chrono/high_resolution_clock/now
-
第二个可能会稍微(非常稍微)快一些,而且安全性会无限降低。
-
您可以将操作展开为
while (ptr) { total += ptr->data; ptr = ptr->next; if (ptr) ptr = ptr->next; },这基本上节省了加法、模数和寄存器,但保持了相同数量的分支。也许一个聪明的优化编译器无论如何都会这样做。我认为这是过早的优化,正如其他人已经引用的那样,由于缓存未命中的机会增加,链表遍历通常很慢。最后,要么使用您的第一个示例,要么使用我的 - 选择应该主要是使用最清楚地向任何阅读代码的人描述意图的示例。
标签: c++ performance linked-list singly-linked-list