How to Improve the recursion efficiency of JavaScript

Source: Internet
Author: User
Nicholas explains how to improve the recursion efficiency of JavaScript! Another killer that affects JavaScript performance is recursion. As mentioned in the previous section, the memoization technology can be used to optimize recursive functions for numerical calculation. However, memoization is not omnipotent, not all recursive functions can be optimized using the memoization technology. This article introduces these situations and introduces the solution, that is, to convert Recursion TO iteration. At the same time, pay attention to the following, the solution introduced at the end of this article is not the final solution. It also needs to be integrated with the optimization loop solution in the previous section to achieve the best effect. [Original] speed up your JavaScript, Part 3 [author] Nicholas C. zakas [Translator] mingda is the translation of the original article: recursion is one of the major opponents of slow script running speed. Too many recursion will make the browser slow down until it dies or suddenly exits inexplicably, so we must solve this series of performance problems in JavaScript. In this series Article In the second article, I briefly introduced how to use the memoization technology to replace too many recursive calls in functions. Memoization is a technology that can cache previous computation results, so that we do not need to recalculate the computed results. Memoization is very useful for calculating the number of functions through recursion. The memoizer I am using is written by crockford and mainly applies to recursive operations that return integers. Of course not all recursive functions return integers, so we need a more general memoizer () function to process more types of recursive functions. Function memoizer (fundamental, cache) {cache = cache ||{}; var shell = function (ARG) {If (! (ARG in cache) {cache [Arg] = fundamental (shell, ARG) ;}return cache [Arg] ;}; return shell ;} functions of this version are slightly different from those written by crockford. First, the order of parameters is reversed. The original function is set as the first parameter, and the second parameter is the cache object, which is an optional parameter, not all recursive functions contain initial information. Within the function, I convert the cached object type from an array to an object, so that this version can adapt to recursive functions that do not return integers. In Shell functions, I use the in operator to determine whether a parameter is included in the cache. This method is more secure than the test type is not undefined, because undefined is a valid return value. We still use the Fibonacci series mentioned earlier to explain: var Fibonacci = memoizer (function (recur, n) {return recur (n-1) + recur (n-2 );}, {"0": 0, "1": 1}); similarly, If you execute the Fibonacci (40) function, you can only call the original function 40 times, instead of exaggerating 331,160,280 times. Memoization recursion for those result sets with strict definitions Algorithm It's amazing. However, there are still many recursive algorithms that are not suitable for optimization using the memoization method. When I was at school, a professor always insisted that iteration can be used to replace any situations where recursion is used. In fact, recursion and iteration are often used as complementary methods, especially when another problem occurs. The technology for converting recursive algorithms into iterative algorithms is also independent of the development language. This is very important for Javascript, because many things are restricted in the execution environment (the importance in Javascript is greater, though, because the resources of the execution environment are so restrictive .). Let's review a typical recursive algorithm, such as Merge Sorting, which requires the following Code : Function Merge (left, right) {var result = []; while (left. length> 0 & right. length> 0) {If (left [0] <right [0]) {result. push (left. shift ();} else {result. push (right. shift () ;}} return result. concat (left ). concat (right);} // uses the recursive Merge Sorting Algorithm function mergesort (items) {If (items. length = 1) {return items;} var middle = math. floor (items. length/2), left = items. slice (0, middle), Right = I Tems. Slice (middle); Return Merge (mergesort (left), mergesort (right);} calls the mergesort () function to process an array, and then returns the sorted array. Note that every time you call the mergesort () function, there will be two recursive calls. This algorithm cannot be optimized using memoization, because every result is calculated and used only once, and it is useless even if the result is buffered. If you use the mergesort () function to process an array containing 100 elements, a total of 199 calls will be made. The array of the 1000 elements will be called 1999 times. In this case, our solution is to convert recursive algorithms into iterative algorithms, that is, to introduce some loops (for more information about algorithms, see list processing: sort again, naturally): // function mergesort (items) {If (items. length = 1) {return items;} var work = []; for (VAR I = 0, Len = items. length; I <Len; I ++) {work. push ([items [I]);} work. push ([]); // In case of odd number of items for (VAR Lim = Len; Lim> 1; Lim = (lim + 1)/2) {for (var j = 0, K = 0; k <L Im; j ++, K + = 2) {work [J] = Merge (work [K], work [k + 1]);} work [J] = []; // In case of odd number of items} return work [0];} This Merge Sorting Algorithm uses a series of loops instead of recursion for sorting. Because the Merge Sorting first splits the array into several arrays with only one element, this method performs this operation more explicitly, rather than using recursive functions. The work array is initialized to an array containing a bunch of arrays with only one element. In the loop, two arrays are merged each time, and the Merged Results are put back into the work array. After the function is executed, the sorting result is returned by the first element in the work array. In the implementation of this merge sort, no recursion is used, and this algorithm is also implemented. However, this introduces a large number of loops. The number of loops is based on the number of elements in the array to be sorted. Therefore, we may need to revise them using the technology discussed in the previous article, handle these additional overhead. To sum up the basic principles, you should be cautious when using recursion. Memoization and iteration are two solutions that replace recursion. The most direct result is to avoid the dialog box that prompts that the script is out of control.

 

Unknown Source welcome

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.