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

c#程序运行缓慢

我以前遇到过类似的问题,并且发现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)

小事情,但他们可能会加快速度。