C++ 优化c+中的指针副本+;
所以今天我尝试优化链表遍历。我的想法是,将cur复制到最后一个,然后再复制到cur的旁边,效率较低,而我只能复制一个cur。希望下面的代码有助于使其更清晰:C++ 优化c+中的指针副本+;,c++,pointers,optimization,C++,Pointers,Optimization,所以今天我尝试优化链表遍历。我的想法是,将cur复制到最后一个,然后再复制到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(i
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;
}
有人能解释为什么翻滚修剪()函数如此之慢吗?您的编译器显然在优化
trim()
比它能优化的要多得多。这是一个保持代码简单易读的最好例子,只有在通过性能分析发现瓶颈后才尝试任何优化。即使这样,你也很难在这样一个简单的循环中击败编译器。显然,你的编译器对trim()
的优化程度远远超过了它的rollup\u trim()
。这是一个保持代码简单易读的最好例子,只有在通过性能分析发现瓶颈后才尝试任何优化。即使这样,在这样一个简单的循环中,您也很难击败编译器。以下是生成的两个函数的程序集的相关部分:(只是while循环:
修剪:
滚柱装饰:
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:
现在,让我们试着描述一下每种情况下会发生什么:
在trim中,执行以下步骤:
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个比较
- 翻滚修剪:2个指针,1个比较,1个跳跃
- 修剪:3个指针副本,1个比较,1个跳转
- 翻滚修剪:4次指针复制,2次比较,1次跳转
std::list
)以下是为两个函数生成的程序集的相关部分:(仅while循环): 修剪: 滚柱装饰:
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:
现在,让我们试着描述一下每种情况下会发生什么:
在trim中,执行以下步骤:
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个比较
- 翻滚修剪:2个指针,1个比较,1个跳跃
- 修剪:3个指针副本,1个比较,1个跳转
- 翻滚修剪:4次指针复制,2次比较,1次跳转
std::list
)您在发行版中编译过这个基准测试吗?另外,请注意,一般来说,
clock()
对于度量对性能敏感的代码来说是一个糟糕的函数(它只精确到