javascript indexOf有数百万的比赛

时间:2015-03-16 20:37:59

标签: javascript google-chrome indexof

我试图从文件中提取几行代表某些XML元素。 用户使用简单的<input type="file">标记提供文件,然后将此文件作为带有FileReader的文本读取,并作为此函数的参数提供:

var relevantDelimiters = [{"begin":"<header>","end":"</header>"}
,{"begin":" <someElement>","end":"</someElement>"}];

function dealWithString(invalidXML) {
  var validXML = "";
  for (var i=0; i<relevantDelimiters.length; i++) {
    delimiter = relevantDelimiters[i];
    while (invalidXML.indexOf(delimiter.begin) != -1) {
      //while there are relevant elements of this kind left: 
      startPos = invalidXML.indexOf(delimiter.begin);
      endPos = invalidXML.indexOf(delimiter.end); 
      //append to end result:
      validXML+=invalidXML.substring(startPos,endPos+delimiter.end.length)+"\n";
      //take this item out of the input to process next item
      invalidXML = invalidXML.replace(invalidXML.substring(startPos,endPos+delimiter.end.length),"");
    }
  }
  //return fixed data
  return validXML;
}

这种方法似乎在输入文本文件中只有少量匹配就可以正常工作,但是如果文件大小为1.5MB,脚本就会卡住(使用谷歌浏览器运行,使其无法响应) 。此文件包含大约一百万个&#34;相关元素&#34;,表示来自relevantDelimiters的匹配。

如何优化此功能?

2 个答案:

答案 0 :(得分:3)

而不是重复&#34;从输入中取出项目&#34;通过在其上调用replace,您应该使用indexOf的第二个参数:fromIndex。这样,它会在给定索引之后搜索下一个出现的事件,并且您可以循环遍历非常大的输入而无需触摸它。

function dealWithString(invalidXML) {
  var validXML = "";
  for (var i=0; i<relevantDelimiters.length; i++) {
    var delimiter = relevantDelimiters[i],
        pos = 0,
        startPos;
    while ((startPos = invalidXML.indexOf(delimiter.begin, pos)) != -1) {
      //while there are relevant elements of this kind left:
      var endPos = invalidXML.indexOf(delimiter.end, startPos);
      // assert(endPos != -1) - otherwise this could go horribly wrong
      pos = endPos+delimiter.end.length;
      //append to end result:
      validXML += invalidXML.slice(startPos, pos) + "\n";
    }
  }
  return validXML;
}

答案 1 :(得分:0)

花费的时间在哪里?我假设你可以把这个大的同步动作分解成几个异步的希望。 (每次迭代,您可以在恢复之前存储索引和设置超时。这样您就不会锁定UI线程。