Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/411.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在javascript中优化代码_Javascript_Arrays_Performance_Optimization - Fatal编程技术网

如何在javascript中优化代码

如何在javascript中优化代码,javascript,arrays,performance,optimization,Javascript,Arrays,Performance,Optimization,我认为(下面的)代码是优化的(只需使用比相同逻辑的初始版本更少的变量)。 我如何才能真正知道它是否得到了适当的优化 在优化过程中应考虑哪些因素? 这是密码( ) 功能处理(arr){ var处理=[]; 对于(变量i=0,len=arr.length;i 1){ 对于(var j=0,jlen=nodes.length;j广义上的优化将涉及简化代码、预计算重复使用的结果,以及组织代码以便重用更多的结果 您的fiddle代码在分析中产生了以下结果 Logical LOC: 26 Mean par

我认为(下面的)代码是优化的(只需使用比相同逻辑的初始版本更少的变量)。

  • 我如何才能真正知道它是否得到了适当的优化

  • 在优化过程中应考虑哪些因素?

    这是密码( )

    功能处理(arr){
    var处理=[];
    对于(变量i=0,len=arr.length;i 1){
    
    对于(var j=0,jlen=nodes.length;j广义上的优化将涉及简化代码、预计算重复使用的结果,以及组织代码以便重用更多的结果

    您的fiddle代码在分析中产生了以下结果

    Logical LOC: 26
    Mean parameter count: 3
    Cyclomatic complexity: 7
    Cyclomatic complexity density: 27%
    Maintainability index: 104
    
    代码行(LOC)–表示代码中的大致行数。计数基于IL代码,因此不是源代码文件中的精确行数。非常高的计数可能表示某个类型或方法试图做太多的工作,应该拆分。它还可能表示该类型或方法可能难以维护

    可维护性指数–计算一个介于0和100之间的指数值,表示代码的相对易维护性。高值意味着更好的可维护性。颜色编码评级可用于快速识别代码中的故障点。绿色评级介于20和100之间,表示代码具有良好的可维护性不可维护性。黄色评级介于10和19之间,表示代码可适度维护。红色评级介于0和9之间,表示可维护性较低

    圈复杂度–衡量代码的结构复杂度。它是通过计算程序流中不同代码路径的数量来创建的。具有复杂控制流的程序将需要更多的测试来实现良好的代码覆盖率,并且不易维护

    使用javascript代码检查代码复杂性

    参考文献:


    (为您提供了优化时应牢记的不同技术)

    当前,您的代码具有
    O(n^2)
    复杂性。这是由
    过程中
    arr
    的外循环引起的,然后调用
    findIndexes
    ,它再次循环
    arr

    您可以将其简化为一个
    O(n)
    算法,该算法在数组中循环两次:

    function process(arr) {
        var result = [];
        var counter = {}, counts = {};
    
        var len = arr.length;
        for(var i = 0; i < len; i++){   
            var value = arr[i];
    
            counter[value] = 1;
            counts[value] = (counts[value] || 0) + 1;
        }
    
        for(var i = 0; i < len; i++){   
            var value = arr[i];
    
            if(counts[value] == 1) {
                result.push(value);   
            } else {
                result.push(value + "(" + counter[value]++ + ")");
            }
        }
    
        return result;
    }
    
    功能处理(arr){
    var结果=[];
    变量计数器={},计数={};
    var len=阵列长度;
    对于(var i=0;i
    您可以在单个循环中完成:

    function process2(arr) {
        var out = arr.slice(0),
            seen = {},
            len = arr.length,
            i, key, item, count;
    
        for (i = 0; i < len; ++i) {
            key = out[i];
            item = seen[key];
            if (!item) {
                // firstIndex, count
                seen[key] = item = [i, 0];
            }
            count = ++item[1];
            if (count > 1) {
                if (count === 2) {
                    out[item[0]] = key + '(1)';
                }
                out[i] = key + '(' + count + ')';
            }
        }
        return out;
    }
    
    // input
    var arr = ['aa', 'bb', 'bb', 'aa', 'cc', 'dd', 'cc', 'ff']
    
    console.time('p2');
    console.log(process2(arr));
    console.timeEnd('p2');
    
    功能处理2(arr){
    var out=arr.slice(0),
    seen={},
    len=arr.长度,
    i、 键、项、计数;
    对于(i=0;i1){
    如果(计数==2){
    out[项目[0]]=键+'(1)';
    }
    out[i]=key+'('+count+');
    }
    }
    返回;
    }
    //输入
    var arr=['aa','bb','bb','aa','cc','dd','cc','ff']
    控制台时间('p2');
    console.log(process2(arr));
    控制台。时间结束('p2');
    

    从基准测试来看,
    process2
    大约比
    process1
    快2倍。这只是解决问题的第一步。

    还有另一种方法可以在较少更改的情况下优化代码:

    在您的特定情况下,尽管所有以前的条目都已处理过,但您仍会遍历每个新找到的条目的整个数组,因此应该可以通过将当前索引传递给FindIndex来进一步优化:

    function findIndexes(arr,val, fromIndex){
      var node = [];
      for(var i=fromIndex,len=arr.length;i<len;i++){
          if(arr[i] === val){
              node.push(i);
          }
      }
      return node;
    }
    
    函数findIndex(arr、val、fromIndex){
    var节点=[];
    
    对于(var i=fromIndex,len=arr.length;i以下是一个不使用嵌套循环并使用对象存储键信息的示例:

    var obj = {};
    
    // loop over the array storing the elements as keys in the object
    // if a duplicate element is found, increment the count value
    for (var i = 0, l = arr.length; i < l; i++) {
      var key = arr[i];
      if (!obj[key]) obj[key] = { count: 0, level: 0 };
      obj[key].count++;
    }
    
    // remove all the key/values where the count is 1
    // ie there are no duplicates
    for (var p in obj) {
      if (obj[p].count ===  1) delete obj[p];
    }
    
    // for each element in the original array, increase its 'level'
    // amend the element with the count
    // reduce the count
    for (var i = 0, l = arr.length; i < l; i++) {
        var key = arr[i];
        if (obj[key] && obj[key].count > 0) {
          obj[key].level++;
          arr[i] = key + '(' + obj[key].level + ')';
          obj[key].count--;
        }
    }
    
    var obj={};
    //在数组上循环,将元素作为键存储在对象中
    //如果发现重复元素,则增加计数值
    对于(变量i=0,l=arr.length;i0){
    obj[key].level++;
    arr[i]=key+'('+obj[key].level+');
    obj[key]。计数--;
    }
    }
    

    您的代码可能会针对性能进行优化,但为了可读性,这是另一个问题……如果这里没有问题,这似乎是属于您的。如果这会使您的页面不负责任(如果您使用html5),您可以使用web worker执行这种循环操作(在单独的线程中)@SebasSBM OP绝对不应该这样做,这是一种不好的做法。这是如何让它更快的呢?如果你能解释这些参数,那就太好了。谢谢你的参考链接。非常有用。回答了我的第二个问题。这并没有产生正确的输出:
    [“aa(1)”,“bb(1)”,“aa(1)”,“cc(1)”,“dd”,“cc(1)”,“ff”]
    感谢您注意到,@Evantimboli。现在正确的结果是:
    [“aa(1)”,“bb(1)”,“bb(2)”,“aa(2)”,“cc(1)”,“dd”,“cc(2)”,“ff”]
    我认为您的答案肯定会提高性能,我也会将其标记为答案
    var obj = {};
    
    // loop over the array storing the elements as keys in the object
    // if a duplicate element is found, increment the count value
    for (var i = 0, l = arr.length; i < l; i++) {
      var key = arr[i];
      if (!obj[key]) obj[key] = { count: 0, level: 0 };
      obj[key].count++;
    }
    
    // remove all the key/values where the count is 1
    // ie there are no duplicates
    for (var p in obj) {
      if (obj[p].count ===  1) delete obj[p];
    }
    
    // for each element in the original array, increase its 'level'
    // amend the element with the count
    // reduce the count
    for (var i = 0, l = arr.length; i < l; i++) {
        var key = arr[i];
        if (obj[key] && obj[key].count > 0) {
          obj[key].level++;
          arr[i] = key + '(' + obj[key].level + ')';
          obj[key].count--;
        }
    }