我在C#中有一个程序,其psuedocode看起来像这样。程序运行正常,但需要5天才能运行。我需要每天运行这个新标准。 我们正在尝试标记生物学书籍中的每个花卉名称。每天它都是.txt格式的不同教科书或期刊。我们正在使用Lucene搜索来加快速度。我们在数据库中有FLowerFamilyID列表。我们还有FlowerID | FlowerCommon名称在csv文件中。这个csv文件有大约10,000个条目。
步骤1 //从SQL服务器获取FlowerFamilyID&转储文本文件。这有大约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,花卉列表)。返回在该书/期刊中找到的所有花朵
步骤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
}
我试过这个,&amp;它在5天内完成。但我需要在一天之内完成这项工作,bcoz结果用于进一步分析。因此,我将csv文件拆分为10个不同的文件和作业 在2天内完成。团队负责人告诉我使用多个线程来提高速度。我不知道该怎么做。有人可以帮帮我吗?
由于 [R
答案 0 :(得分:-1)
我之前遇到过类似的问题,并且发现foreach通常是个问题。在这里,您将迭代10000个条目的列表。虽然这本身不是问题,但你没有说过花类的样子。它只是几个字符串?
现在,当你处理一个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实例
然后你在花上执行某种字符串操作(我不知道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 - 我认为你使用value作为变量名。请记住,每次调用外部方法时,事情都会变慢
这些都是基于你放在这里的所有假设。
另一件要尝试的是不使用强类型名称。例如
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)
小事情,但它们可能会加快速度。