JavaScript循环效率/性能

时间:2015-10-02 15:02:12

标签: javascript string performance

我目前正在开展Codewars挑战,http://www.codewars.com/kata/your-order-please。任务是取一个字符串并根据在字符串的每个单词中找到的值重新排序单词,例如:“is2 Thi1s T4est 3a”该函数应返回“Thi1s is2 3a T4est”。

我编写了一个成功传递所有测试的解决方案并返回正确的字符串。 https://jsfiddle.net/louisstanard/5hygz6wb/

function order(words){
  var ordered = [];
  var arr = words.split(' ');
  var n = 1;
  while (n <= arr.length) {
    for (var i = 0; i < arr.length; i++) {
      var stringArr = arr[i].split('');
      stringArr.forEach(function(currentValue, index) {
        if (parseInt(currentValue) === n) {
          ordered.push(arr[i]);
          n++;
        }
      });
    }  
  }
  return ordered.join(' ');
}

我的问题是,当我尝试提交解决方案时,我收到一条错误消息“进程已终止。完成时间超过6000毫秒”。我选择使用while循环,因为我想继续迭代字符串中的每个单词以查找数字,直到我构建了一个长度与原始数组相同的新数组。

我是编写更多高性能JS的新手,但我知道虽然循环(可能是嵌套在一段时间内)可能是非常昂贵的操作。有没有人知道为什么这可能需要太长时间才能运行?我没有看到任何明显的性能问题吗?或者也许是一个更好的方法?谢谢!

3 个答案:

答案 0 :(得分:0)

这是另一种方法:

function order(words){
  return words
    .split(' ')
    .sort(function( wordA, wordB ) {
      var numA = +(wordA.match(/\d+/g)[0]);
      var numB = +(wordB.match(/\d+/g)[0]);
      return numA - numB;
    })
    .join(' ');
}

答案 1 :(得分:0)

查看Fiddle here的更新。在我的Chrome浏览器上,显示比原始浏览器快一个数量级。

function orderNew(words){
  var ordered = [];
  var arr = words.split(' ');  

    arr.forEach(function(item, index){
        var match = /\d+/.exec(item);
        ordered[parseInt(match[0])] = item;
    });
    return ordered.join(' ');
}

答案 2 :(得分:0)

您的代码运行缓慢,因为您执行了大量不必要的计算:

  • 你不要缓存两个数组的长度,所以每次迭代,你都要再次查看长度。
  • 你有3个循环,其中一个循环就足够了。
  • 你检查单词中的每个字母,而parseInt(单词,10)已经返回单词中的第一个数字,所以循环遍历这些字母是没用的。
  • 你的while循环和第一个for循环基本上是一样的,因为它们都从0开始并以原始字符串包含的单词数量结束。
  • 将结果推送到数组而不是仅设置ordered [i] = arr [i]。
  • 你的for循环不包含中断,所以你总是继续循环,即使你已经找到了正确的结果(在这种情况下是数字)。
  • 尝试构建新数组直到它具有原始数组的长度的逻辑是有缺陷的,因为如果你完成循环,如果你的代码是正确的,新数组将始终具有原始数据的长度。 / LI>

简而言之,是的,使用其他人发布的技术之一会更高效,因为该代码更优化且不包含冗余逻辑。