简体   繁体   English

这两个节目的表演是一样的吗?

[英]Are the Performances of these two programs the same?

Say for example you have a linked list 1->2->3->4->5->6->NULL and you want to calculate the total of the even indices of that linked list (assuming that the 1st index starts with 1 and the size of the linked list is even)例如,假设您有一个链表 1->2->3->4->5->6->NULL 并且您想要计算该链表的偶数索引的总数(假设第一个索引以1且链表大小为偶数)

First Approach第一种方法

int total = 0;
int count = 0;
Node *ptr = head;
while(ptr != NULL)
{
    if(count % 2 == 0)
     {
       total += ptr->data;
     }
     count++;
     ptr = ptr->next;
}
 

Second Approach第二种方法

int total = 0;
Node *ptr = head;
while(ptr != NULL)
{  
    total += ptr->data;
     ptr = ptr->next->next;
}

So after I did these two approaches do they have the same performance?那么在我做了这两种方法之后,它们的性能是否相同?

I read your question again and will answer that probably the second method is slightly faster.我再次阅读了您的问题,并会回答可能第二种方法稍快一些。

Now, the comments section immediately highlighted that it's also more dangerous.现在,评论部分立即强调它也更危险。 You have actually specified that the assumption is the number of nodes in the list is even.您实际上已指定假设列表中的节点数是偶数。 If that is a guaranteed and enforceable precondition, then it's technically okay to do this.如果这是一个有保证且可执行的前提条件,那么在技术上可以这样做。

Even a smart optimizing compiler has no way of knowing about this precondition of even list-length, so the very best it could likely achieve is to recognize that count is only used for controlling whether total is updated and so the loop could be unrolled as follows:即使是一个智能优化编译器也无法知道这个偶数列表长度的前提条件,所以它可能实现的最好的结果是认识到count仅用于控制是否更新total ,因此可以按如下方式展开循环:

// Possible automatic compiler optimization of First Approach
while (ptr)
{
    total += ptr->data;
    ptr = ptr->next;

    // Skip over every second node
    if (ptr) ptr = ptr->next;
}

In basic terms, what we now have is one more pointer test (branch) per loop iteration than your Second Approach has.基本而言,我们现在拥有的每个循环迭代比您的第二种方法多一个指针测试(分支)。 This results in more instructions (specifically a branching instruction) and so the code will technically be (slightly) slower.这会导致更多指令(特别是分支指令),因此代码在技术上会(稍微)慢一些。

Of course, the actual impact of this is likely to be very small.当然,这种情况的实际影响很可能很小。 Your main bottleneck is pointer indirection and fetches from memory, rather than the pointer test itself.您的主要瓶颈是指针间接并从 memory 获取,而不是指针测试本身。 If the memory used by each node is not mostly contiguous, you'll run into caching problems on large lists (which in practice affects performance by about a factor of 100).如果每个节点使用的 memory 大部分不是连续的,那么您将在大型列表上遇到缓存问题(实际上这会影响性能大约 100 倍)。

What I mean to indicate by all the above, is that the benefits of your special optimization based on the precondition of even list-length suffers from diminishing returns.以上所有内容我的意思是,基于偶数列表长度的前提条件的特殊优化的好处是收益递减。

Given that it is inherently unsafe unless very well-documented in the code and/or protected by a list "evenness" test (if you store the node count somewhere), I would recommend coding defensively by using your First Approach or use my equivalent and (arguably) tidier version of that.鉴于它本质上是不安全的,除非在代码中有很好的记录和/或受列表“均匀性”测试保护(如果您将节点计数存储在某处),我建议使用您的第一种方法进行防御性编码或使用我的等效方法和(可以说)更整洁的版本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM