[英]Optimizing pointer copies in c++
因此,今天我正在尝试优化链表遍历。 我的想法是,当我只能复制一份时,复制cur到最后再复制到cur的效率较低。 希望下面的代码可以使它更清晰:
struct Node{
int body;
Node* next;
};
Node* construct(int len){
Node *head, *ptr, *end;
head = new Node();
ptr = head;
ptr->body = 0;
for(int i=1; i<len; i++){
end = new Node();
end->next = NULL;
end->body = i;
ptr->next = end;
ptr = end;
}
return head;
}
int len(Node* ptr){
int i=1;
while(ptr->next){
ptr = ptr->next;
i += 1;
}
return i;
}
void trim(Node* head){
Node *last, *cur;
cur = head;
while(cur->next){
last = cur;
cur = cur->next;
}
last->next = NULL;
}
void tumble_trim(Node* head){ // This one uses less copies per traverse
Node *a, *b;
a = head;
while(true){
if(!a->next){
b->next = NULL;
break;
}
b = a->next;
if(!b->next){
a->next = NULL;
break;
}
a = b->next;
}
}
int main(){
int start;
Node *head;
start = clock();
head = construct(100000);
for(int i=0; i<5000; i++){
trim(head);
}
cout << clock()-start << endl;
start = clock();
head = construct(100000);
for(int i=0; i<5000; i++){
tumble_trim(head);
}
cout << clock()-start << endl;
}
但是结果令我非常惊讶。 实际上,副本较少的副本速度较慢:
1950000
2310000 // I expected this one to be faster
谁能解释为什么tumble_trim()函数这么慢?
您的编译器显然比tumble_trim()
更能优化trim()
tumble_trim()
。 这是保持代码简单易读, 仅在通过性能分析确定瓶颈后才尝试进行任何优化的主要示例。 即使那样,您也将很难在这样的简单循环中击败编译器。
这是两个函数生成的程序集的相关部分:(仅while循环:
修剪:
LBB2_1: ## =>This Inner Loop Header: Depth=1
movq %rcx, %rax
movq %rdi, %rcx
movq 8(%rdi), %rdi
testq %rdi, %rdi
jne LBB2_1
## BB#2:
tumbletrim:
LBB3_1: ## =>This Inner Loop Header: Depth=1
movq %rdi, %rax
movq 8(%rax), %rdx
testq %rdx, %rdx
je LBB3_2
## BB#3: ## in Loop: Header=BB3_1 Depth=1
movq 8(%rdx), %rdi
testq %rdi, %rdi
movq %rdx, %rcx
jne LBB3_1
## BB#4:
movq $0, 8(%rax)
popq %rbp
ret
LBB3_2:
现在,让我们尝试描述每个事件:
在修剪中,执行以下步骤:
换句话说,每个迭代包含3个副本,1个测试和1个跳转指令。
现在,您巧妙地优化了tumbletrim:
换句话说,在最后的迭代中,当您退出循环时,执行的指令总数为:
在所有其他迭代中,总计数如下:
因此,在极少数情况下(退出循环之前的最后一次迭代), 当且仅当跳转指令比在寄存器之间复制指针大小的值便宜(不是)时,您的实现才便宜
在常见情况下(所有其他迭代,您的实现具有更多的副本和更多的比较。(更多的指令,给指令高速缓存带来更多的负载。更多的分支语句,向分支缓存带来更多的负载)
现在,如果你在所有关心摆在首位的表现,那么有两个你做错了更为基本的东西:
std::list
( std::list
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.