Not using recursion will anyway cause you to rewrite your algorithm using your own "Stack", which will eventually be subjected to similar conditions while execution.
You can customize stack size based on need of your algorithm, but if you look at WPF/Silverlight and normal UI related algorithms, they all are recursive in nature and every click, every key press and every notifications go through lot of recursive methods.
Although the speed may vary depending upon the algorithm and complexity, but creating separate non recursive algorithm will make task more complex as you will be doing all data store operations by yourself using lists, stacks etc.
This is quite design vs performance issue, if you want better performance, then your non recursive algorithm will execute faster, but it will take longer to design and implement such algorithm. Where else if you want a quicker solution then you can write recursive algorithm that will be slower in execution but if the difference is only few milliseconds or microseconds then its not worth doing it.
Loop always outperfroms recursion since stack always has more overhead than your state. A lot of threading operations heavily walk the stack so you get further decline.
However, readability is a big plus so I will personally use recursion unless I need every drop of perfromance such as in image processing operations or I expect my stacks to grow very large - although stack overflow almost exclusively due to bugs.
在 Microsoft 当前的 C# 编译器实现中,未进行尾调用优化。这使得递归的函数算法深度溢出堆栈。虽然我不建议在 C# 中使用深度递归算法,但不深度递归的方法根本不会给您带来任何问题。
In Microsoft's current implementation of the C# compiler, tail call optimizations are not made. This makes functional algorithms which recurse deeply overflow the stack. While I would not recommend using deeply recursive algorithms in C#, methods that do not recurse deeply should not cause you any problem at all.
The reason recursion in functional languages is good practice isn't because of tail recursion optimizations; it's good practice because it's a powerful, simple way of expressing a lot of algorithms. The optimizations are just gravy, and anyway tail call optimizations aren't relevant to all recursive functions.
So with that in mind, it's perfectly great practice to build recursive methods in c#, if that's the most natural way of expressing your algorithm. Obviously, if it turns out to have stack depth issues, it might make sense to make it iterative. But to take a naturally recursive algorithm and make it iterative without first knowing it's an issue is premature optimization, and could make your code unnecessarily complicated and hard to read in exchange for little performance gain.
发布评论
评论(5)
无论如何,不使用递归都会导致您使用自己的“堆栈”重写算法,最终在执行时会遇到类似的条件。
您可以根据算法的需要自定义堆栈大小,但如果您查看 WPF/Silverlight 和普通 UI 相关算法,它们本质上都是递归的,每次单击、每次按键和每个通知都会经历很多递归方法。
查看使用自定义堆栈大小创建线程,
尽管速度可能会有所不同取决于算法和复杂性,但是创建单独的非递归算法将使任务变得更加复杂,因为您将使用列表、堆栈等自己完成所有数据存储操作。
这是一个设计与性能问题,如果您想要更好的性能,那么您的非递归算法将执行得更快,但设计和实现此类算法将花费更长的时间。在其他地方,如果您想要更快的解决方案,那么您可以编写执行速度较慢的递归算法,但如果差异只有几毫秒或几微秒,那么就不值得这样做。
Not using recursion will anyway cause you to rewrite your algorithm using your own "Stack", which will eventually be subjected to similar conditions while execution.
You can customize stack size based on need of your algorithm, but if you look at WPF/Silverlight and normal UI related algorithms, they all are recursive in nature and every click, every key press and every notifications go through lot of recursive methods.
Check out Creating Thread with Custom Stack Size,
Although the speed may vary depending upon the algorithm and complexity, but creating separate non recursive algorithm will make task more complex as you will be doing all data store operations by yourself using lists, stacks etc.
This is quite design vs performance issue, if you want better performance, then your non recursive algorithm will execute faster, but it will take longer to design and implement such algorithm. Where else if you want a quicker solution then you can write recursive algorithm that will be slower in execution but if the difference is only few milliseconds or microseconds then its not worth doing it.
循环总是优于递归,因为堆栈总是比状态有更多的开销。许多线程操作会大量遍历堆栈,因此您的性能会进一步下降。
然而,可读性是一个很大的优点,所以我个人会使用递归,除非我需要每一滴性能,例如在图像处理操作中,或者我预计我的堆栈会变得非常大 - 尽管堆栈溢出几乎完全是由于错误造成的。
Loop always outperfroms recursion since stack always has more overhead than your state. A lot of threading operations heavily walk the stack so you get further decline.
However, readability is a big plus so I will personally use recursion unless I need every drop of perfromance such as in image processing operations or I expect my stacks to grow very large - although stack overflow almost exclusively due to bugs.
在 Microsoft 当前的 C# 编译器实现中,未进行尾调用优化。这使得递归的函数算法深度溢出堆栈。虽然我不建议在 C# 中使用深度递归算法,但不深度递归的方法根本不会给您带来任何问题。
In Microsoft's current implementation of the C# compiler, tail call optimizations are not made. This makes functional algorithms which recurse deeply overflow the stack. While I would not recommend using deeply recursive algorithms in C#, methods that do not recurse deeply should not cause you any problem at all.
函数式语言中的递归是良好实践的原因并不是因为尾递归优化;而是因为尾递归优化。这是一个很好的实践,因为它是表达许多算法的一种强大而简单的方式。这些优化只是肉汁,无论如何尾部调用优化并不与所有递归函数相关。
因此,考虑到这一点,如果这是表达算法的最自然方式,那么在 C# 中构建递归方法是非常好的实践。显然,如果事实证明存在堆栈深度问题,那么对其进行迭代可能是有意义的。但是,在不首先知道这是一个问题的情况下采用自然递归算法并使其迭代是不成熟的优化,并且可能会使您的代码不必要地复杂且难以阅读,而性能提升却很小。
The reason recursion in functional languages is good practice isn't because of tail recursion optimizations; it's good practice because it's a powerful, simple way of expressing a lot of algorithms. The optimizations are just gravy, and anyway tail call optimizations aren't relevant to all recursive functions.
So with that in mind, it's perfectly great practice to build recursive methods in c#, if that's the most natural way of expressing your algorithm. Obviously, if it turns out to have stack depth issues, it might make sense to make it iterative. But to take a naturally recursive algorithm and make it iterative without first knowing it's an issue is premature optimization, and could make your code unnecessarily complicated and hard to read in exchange for little performance gain.
当您需要递归时,您就需要它,例如深度优先树遍历或递归下降解析。
如果您可以选择,例如使用递归而不是循环,那么这可能是您所使用的语言的函数。保持简单。
When you need recursion, you need it, like for depth-first tree walking, or recursive-descent parsing.
If you have a choice, like using recursion instead of a loop, then maybe it's a function of what language you're in. Keep it simple.