1. The cycle

Cycle performance

  • Use with caution in loop types provided by Javascriptfor... inBecause each iteration of the loop incurs more overhead,for... inGo back and search at each iterationThe instanceorThe prototype property
  • Don’t usefor-inTo iterate over the members of the group
  • If the loop type is not performance related, how do you choose it? So we’re going to go fromTransactions processed per iterationNumber of iterationsThink about it in two ways
    • Transactions processed in each iteration:
      1. Caching the same values (transactions processed per iteration) to reduce the number of accesses
      2. Traversal in reverse order (if possible)

    for(let i=0; len = items.length; i<len; i++){
      // From here we cache items. Length to reduce each access to items
    }
    
    for(let i = items.length-1; i>=0; i--){
        // In reverse order, we value the items. Length once, and then just check if I >=0 each time,
        // Don't visit items.length every time
    }
    
Copy the code
  • forEachStatement is slower than a normal for loop

2. Conditional statements

Switch Most of the time switch is a little bit more than if-else. When the number of conditions increases, the if-else performance burden increases more than when the number of conditions increases, and when the switch statement compares values in JS, using the congruent operator, there is no type conversion waste. There are several optimization methods as follows: A

  1. Put the most likely conditions first and foremost (this is also what the DIff algorithm in VUE uses) and rank them from highest to least likely.

  2. Another way to reduce conditional judgments is to organize if-else into a series of nested if-else columns. In if-else, the if-else is divided, because using a single if-else usually results in slow execution because each condition needs to be judged.

    if (value ===0) {
        return result0;
    } else if (value ===1) {
        return result1;
    } else if (value ===2) {
        return result2;
    } else if (value ===3) {
        return result3;
    } else if (value ===4) {
        return result4;
    } else if (value ===5) {
        return result5;
    } else if (value ===6) {
        return result6;
    } else {
        return result10;
    }
Copy the code

It can be done like this:

    if(value < 3) {
        if (value ===0) {
            return result0;
        } else if (value===1) {
            return result1;
        } else {
            returnresult2; }}else {
        if (value === 3) {
            return result3;
        } else if (value === 4) {
            return result4;
        } else{}... }Copy the code

If our value===6 then our if-else lookup is going to be higher than the first one

  1. By looking up tables insteadif-else

When we have lots of discrete values to test, if-else and switch are much slower than using lookup tables, which can be built using arrays and plain objects in javascript. Using lookup tables to access data is much faster than using if-else or switch. This is especially true when there are a large number of conditional statements. Such as:

    // We store the result return value in the array first
    var results = [result0, result1, result2, result3, result4];
    
    // Returns the result directly via (option condition)
    return results[value];   
Copy the code

Benefits: We don’t have to write any conditional statements, and even if we increase the number of candidate values, there is little additional performance overhead. The benefits of lookup tables come into play when there is a logical mapping between a single key and a single value, as in the example above. If-else and switch statements are better suited, requiring each option to correspond to a unique action or sequence of actions.

3. The recursion

Recursion can simplify our problems, but it can also cause stack overflow problems, often causing false death when we encounter multiple nested recursions. Therefore, appropriate optimization recursion is also necessary

1. The iteration

Therefore, when we encounter call stack overflow, we should consider an iterative approach. For example, merge sort is the most common algorithm implemented using recursion

    function merge(left, right){
        let 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);
    }
    
    function mergeSort(items){
        if (item.length===1) {
            return items;
        }
        let middle = Math.floor(item.length / 2);
        let left = items.slice(0, middle);
        let right = items.slice(middle);
        return merge(mergeSort(left), mergeSort(right));
    }
    
Copy the code

The mergeSort() function calls itself frequently, and an array of length N will end up calling mergeSort() 2^(n-1) times, which means that if the array is large enough, an overflow error will occur on the JS call stack. That doesn’t mean the algorithm isn’t correct, just that recursion isn’t the best way to do it. So we can do iterative implementation instead

fucntion mergeSort(items) {
    if (items.length ==1) {
        return items;
    }
    let  work = [];
    for (let i=0, len=items.length; i < len; i++){
        work.push([items[i]]);
    }
    work.push([]);
    for (let lim = len; lim>1; lim = (lim+1) /2) {
        for (let j = 0, k=0; k<lim; j++, k+=2){
            work[j] = merge(work[k], work[k+1]);
        }
        work[j] = [];
    }
    return work[0];
}

Copy the code

Memoization

Memoization is a way to avoid duplication of work by caching the results of performing the same task multiple times for use in subsequent computations, as a lot of duplication inevitably occurs when repeated recursive calls are made.

    function memoize(fundamental, cache) {
           let cache = cache || {};
           let shell = function(){
               if(! cache.hasOwnProperty(arg)){ cache[arg] = fundamental(arg); }return cache[arg];
           }
           return shell;
    }
    // Side effects: Can generate closures, resulting in memory leaks, depending on the situation
Copy the code

summary

  • For, while, and do-while loops have similar performance characteristics, and no one loop type is significantly faster or slower than the others

  • Avoid for-in unless you need to iterate over an object with an unknown number of attributes

  • In general, switch is always faster than if-else, but not always the best solution

  • The best way to improve loop novelty is to reduce the amount of computation per iteration and the number of loop iterations

  • The size of the browser’s call stack limits the application of recursive algorithms in JS, and stack overflow errors can cause other code to break