c#程序运行缓慢
本文关键字:缓慢 运行 程序 | 更新日期: 2023-09-27 18:10:45
我有一个c#程序,它的伪代码看起来像这样。这个程序运行得很好,只是需要5天才能运行。我每天都要检查新标准。我们试着给生物书上的每一种花的名字打上标签。每天都是一本不同的教科书或日志。txt格式。我们正在使用Lucene搜索使其更快。我们在数据库中有FLowerFamilyID列表。我们也有FlowerID| FlowerCommon Name在csv文件。这个csv文件大约有10,000个条目。
步骤1//从SQL server &转储为文本文件。它有大约100个条目
FlowerFamilyID FamilyName
1 Acanthaceae
2 Agavaceae
步骤2//csvfile有flowerid, flowercommonname。读取csv文件(大约10000个条目)并将它们存储在列表中,例如:
1|Rose
2|American water willow
3|false aloe
步骤3//在Book/Journal上创建当天的Lucene索引
步骤4//对于datatextfile中的每个familyflowerID调用SearchFlower(flowerfamilyID, flower list)。
返回书/日志中找到的所有花步骤5//在搜索函数中调用Lucene查询解析器&搜索10000个花条目,如果找到,将第一个有分数的条目存储在列表中
public static List<flowerResult> searchText(String flowerfamilyid, List<flower> flowers)
{
DateTime startdate = DateTime.Now;
List<flowerResult> results = new List<flowerResult>();
Document doc = new Document();
foreach (var flower in flowers)
{
string[] separators = { ",", ".", "!", "?", ";", ":", " " };
string value = flower.getFlower().Trim().ToLower();
string[] words = value.Split(separators, StringSplitOptions.RemoveEmptyEntries);
String criteria = string.Empty;
if (words.Length > 1)
criteria = "'"" + value+ "'"";
else
criteria = value;
if (string.IsNullOrEmpty(criteria))
continue;
criteria = criteria.Replace("'r", " ");
criteria = criteria.Replace("'n", " ");
QueryParser queryParser = new QueryParser(VERSION, "body", analyzer);
string special = " +body:" + criteria;
Query query = queryParser.Parse(special);
try
{
IndexReader reader = IndexReader.Open(luceneIndexDirectory, true);
Searcher indexSearch = new IndexSearcher(reader);
TopDocs hits = indexSearch.Search(query, 1);
if (hits.TotalHits > 0)
{
float score = hits.ScoreDocs[0].Score;
if (score > MINSCORE)
{
flowerResult result = new flowerResult(flower.getId(), flower.getFlower(), score);
results.Add(result);
}
}
indexSearch.Dispose();
reader.Dispose();
indexWriter.Dispose();
}
catch (ParseException e)
{//"Could not parse article. Details: " + e.Message);
}
}
return results;
}
public class flower
{
public long flowerID {get;set;}
public string familyname {get;set;}
public string flower {get;set;} //common name
}
我试着运行这个,&它在5天内完成。但我需要在一天内完成,因为结果将用于进一步分析。因此,我将csv文件拆分为10个不同的文件和作业2天完成。组长告诉我使用多线程来提高速度。我不知道该怎么做。有人能帮帮我吗?
谢谢R
我以前遇到过类似的问题,并且发现foreach通常是问题所在。这里迭代的是包含10000个元素的列表。虽然这本身不是问题,但您没有说flowers类是什么样子的。只是几根弦吗?
现在,当你处理foreach并且foreach在一个类上迭代时,你实际做的是创建一个类的实例,将类的指向对象复制到新的实例中,然后处理它。例如,你的类可能是这样的
public class flower
{
public string genus {get;set;}
public string colour {get;set;}
public int occurrences {get;set;}
public int page {get;set;}
public int chapter {get;set;}
public string commonName {get;set;}
}
你就有了一个包含10000个这样的列表。
每次你有foreach,你有
foreach(Flowers myFlower in flowers)
为Flowers
的每次迭代创建一个Flowers实例然后对花执行某种字符串操作(我不知道getFlower做什么,但我假设它返回一个字符串)。
接下来检查字符串是否为null或空,如果有则继续搜索。但是搜索将会很慢,并且最后不需要.Dispose(一旦超出作用域,实例将被销毁,GC将做它需要做的事情)
我将如何做到这一点是只操作foreach在鲜花列表中需要使用的任何东西,而不是其他任何东西。还可以重构查询,使实例化在循环中只执行一次,而不是每次都执行。我发现的另一个技巧是尽可能使用LINQ。你还创建了10000倍的分隔符字符串——把它放到循环之外。
if (words.Length > 1)
criteria = "'"" + value+ "'"";
else
criteria = value;
可以重写为
criterial = words.Length > 1 ? "'"" + value+ "'"" : value;
和
flowerResult result = new flowerResult(flower.getId(), flower.getFlower(), score);
results.Add(result);
可以合并成一行(避免创建新变量)
results.Add(flower.getId(), flower.getFlower(), score);
这里你还调用getFlower第二次对相同的处理数据-我认为你使用的值作为变量名。记住,每次调用外部方法时,速度都会变慢
这些都是基于你在这里写的东西的假设。
另一件要尝试的事情是不要使用强类型名称。例如
IndexReader reader = IndexReader.Open(luceneIndexDirectory, true);
Searcher indexSearch = new IndexSearcher(reader);
TopDocs hits = indexSearch.Search(query, 1);
都很好,但是当我用。net 4运行测试时,var形式更快,这取决于你做什么。因此尝试
var reader = IndexReader.Open(luceneIndexDirectory, true);
var indexSearch = new IndexSearcher(reader);
var hits = indexSearch.Search(query, 1);
我发现它们唯一慢的时候是当你使用原语(如int, double和bool)
小事情,但他们可能会加快速度。