【问题标题】:JS function gradually becomes slowerJS函数逐渐变慢
【发布时间】:2016-02-03 21:02:32
【问题描述】:

我有一个在我的一个页面上运行 onclick 的 js 函数,它使用正则表达式对全局对象数组进行一些文本搜索。

现在每次我运行这个函数时,它开始变得越来越慢 - 第一次是闪电般的速度,第二次需要一秒钟,最后它冻结了 firefox。

这是我的代码的简化版本 -

var search = function(words){
	
	
	var results = [];
	var words = words.toLowerCase();
	var searchArr = words.split(' ');	
	var regexptemplate = '^';
	$.each(searchArr,function(){
		regexptemplate += "(?=.*\\b" + this + ")";
	});
	regexptemplate += ".+";
	var regex = new RegExp(regexptemplate);
		
	for(var index = 0; index < searchObj.length; index++){// check every model sentence
		var curObj = searchObj[index];
		var i;
		// find the actual sentence
		for(i = 1; ((i+1) < 11) && (curObj['level' + (i+1)] != null); i++);	
		
		// get sentence in english and german
		var text = curObj['level' + i];
		var engText = curObj['eng' + i];
		if(engText == null){// make sure not to crash the search just because a sentence wasn't formatted right'
			engText = "";
		}
		
		if ((regex.test(text.toLowerCase()) || regex.test(engText.toLowerCase())) && text.indexOf('{SENTENCE}')!= 0){// check if the word exists in the german or english
			// format sentence to not be too long
			var displayText = text;
			var displayEngText = engText;
			$.each(searchArr,function(ind,word){
				
				var resultWord = '';
				var engResultWord = '';
				if(text.toLowerCase().indexOf(word) != -1){
					resultWord = text.substring(text.toLowerCase().indexOf(word),text.toLowerCase().indexOf(word)+word.length);			
				}
				if(engText.toLowerCase().indexOf(word) != -1){
					engResultWord = engText.substring(engText.toLowerCase().indexOf(word),engText.toLowerCase().indexOf(word)+word.length);							
				}
				displayText = displayText.replace(resultWord,"<mark>" + resultWord + "</mark>").replace(/\r\n/g,"<br>");
				displayEngText = displayEngText.replace(engResultWord,"<mark>" + engResultWord + "</mark>").replace(/\r\n/g,"<br>");
			});
			
			// push the sentence to results
			if(i == 3){
				results.push([displayText,displayEngText,type,curObj['level1'],curObj['level2'],'',text,engText,curObj['eng1'],curObj['eng2'],'',"email" + (index + 1)]);			
			} else if (i == 2){
				results.push([displayText,displayEngText,type,curObj['level1'],'','',text,engText,curObj['eng1'],'','',"email" + (index + 1)]);
			} else {
				results.push([displayText,displayEngText,type,curObj['level1'],curObj['level2'],curObj['level3'],text,engText,curObj['eng1'],curObj['eng2'],curObj['eng3'],"email" + (index + 1)]);
			}
		}		
	}
}

searchObj 是一个全局数组,其中包含大约 1000 个对象。

谁能向我解释为什么这会逐渐变慢?

谢谢

【问题讨论】:

  • 同时提供样本数据(格式)
  • 你能添加`console.log(searchObj.length);在函数的开头,看看它是否没有增长?第一次调用函数和最后一次调用非常慢之间有什么变化吗?你在搜索相同的词吗?
  • @NurBar,尝试将searchObj 的大小减小到,比如说50。然后比较两种情况的执行时间。然后说出你注意到了什么
  • 能否提供一个完整可操作的jsfiddle?
  • 你能看到 Chrome 控制台中的 Timeline > Memory 选项卡,看看它是否一直在增长吗?

标签: javascript jquery


【解决方案1】:

如果不使用您的数据实际测试您的代码,我无法肯定地说任何话,但我可以指出一两件事可能会提高性能。

您完全错误地使用正则表达式,并且过度使用 toLowerCase() 也无济于事。您是 Regex 可以使用不区分大小写的选项 (i) 来忽略大小写,而 Regex match 方法可以用于从文本中提取原始形式的单词,从而消除两者的需要toLowerCase()substring(),大大简化了你的功能,IMO。

现在我看不到您正在使用的对象数组,并且您的函数没有返回任何内容,因此不清楚您要实现什么,但如果您提供更好的示例,我'将能够修改它并为您提供我建议您做的示例。

附:如果定义正确,您甚至可以将正则表达式用作替换方法的一部分,用正则表达式替换所有手动字符串操作。

【讨论】:

  • 嗨,谢谢你的提示,我会调查它,该函数最终会指向在对象中创建搜索结果的其他函数,但这并不重要(它基本上将结果添加到一个节点)。该物体因其他地方的错误而变得越来越大!但感谢您的帮助。
猜你喜欢
  • 2021-05-28
  • 1970-01-01
  • 1970-01-01
  • 2015-05-30
  • 2017-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-27
相关资源
最近更新 更多