我们是否需要手动为链表创建析构函数? [英] Do we need to manually create a destructor for a linked list?
问题描述
我正在阅读 学习 Rust链表太多,我很困惑为什么链表(堆栈)需要一个析构函数.
我认为当列表值超出范围时,列表本身和所有节点都会被清理.只是为了演示吗?
I think when the list value is out of the scope, the list itself, and all nodes would be clean up. Is it just for demonstration?
我对使用和不使用手动析构函数的版本进行了基准测试,我发现不使用析构函数"一个性能更好:
I benchmarked the version with and without a manual destructor and I found the "without destructor" one has better performance:
for _ in 1..30000000 {
let mut list = List::new();
list.push(1);
assert_eq!(list.pop(), Some(1));
}
使用手动析构函数:
real 0m11.216s
user 0m11.192s
sys 0m 0.020s
没有手动析构函数:
real 0m9.071s
user 0m9.044s
sys 0m0.004s
推荐答案
你说得对.该列表将自行清理.正如作者所说:
You are correct. The list would clean itself up. As the author stated:
所有这些都由我们自动处理......一举两得.
All that's handled for us automatically... with one hitch.
然后他们解释了为什么自动处理不好:自动销毁过程为列表的头部调用drop
,然后为第一个元素调用drop
.等等等等.
They then explain why the automatic handling is bad:
The automatic destruction process calls drop
for the head of the list, which in turn calls drop
for the first element. And so on and so on.
这是一个调用函数的函数(有无限可能的重复),它迟早会炸毁你的堆栈.
This is a function calling a function calling a function (with infinite possible repetitions) which will blow up your stack sooner or later.
这个测试会导致这样的堆栈溢出:
This test causes such a stack overflow:
#[test]
fn build_really_big_stack() {
let mut stack = List::new();
for i in 0..1_000_000 {
stack.push(i);
}
}
如果您使用 --release
为两个版本构建,则表明它们的性能几乎相同:
If you build with --release
for both versions, it shows that they perform nearly equally:
#[bench]
fn bench_auto_destructor(b: &mut Bencher) {
b.iter(|| {
let mut list = List::new();
for i in 0..1000 {
list.push(i);
}
assert_eq!(list.pop(), Some(999));
});
}
#[bench]
fn bench_man_destructor(b: &mut Bencher) {
b.iter(|| {
let mut list = ManualDestructorList::new();
for i in 0..1000 {
list.push(i);
}
assert_eq!(list.pop(), Some(999));
});
}
test bench_auto_destructor ... bench: 81,296 ns/iter (+/- 302)
test bench_man_destructor ... bench: 85,756 ns/iter (+/- 164)
只有一个元素,就像在您的基准测试中一样:
With only one element, like in your benchmarks:
test bench_auto_destructor ... bench: 69 ns/iter (+/- 1)
test bench_man_destructor ... bench: 67 ns/iter (+/- 2)
把文章读到最后,它的解释比我的好.
Read the article to the end, its explanation is better than mine.
这篇关于我们是否需要手动为链表创建析构函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!