繁体   English   中英

算法优化-C#

[英]Algorithm optimization - c#

我已经使用了一段时间了,但是我的问题是它有点慢。 我将不得不以某种方式对其进行优化,但是我发现有些困难。 当前速度为O(n ^ 4),在for循环中有一些额外的执行。

我想完成什么?

我在“运行部分”中存储了很多测试用例,在“套件部分”中存储了一些测试用例。 我想比较一下测试用例,以便能够在“套件部分”中查看哪些测试用例失败了。 但是,要获取所有失败的测试用例,我首先必须遍历构建以进行测试运行,然后循环遍历测试运行以获取测试用例,然后将“运行部分测试用例”与“套件部分测试用例”进行比较。第4个循环。

有什么方法或方法可以用来简化这项工作?

该算法在下面列出。

/// <summary>
/// Check if the sortet masterList matches any other testcases. If it does then return them.
/// </summary>
/// <algorithm>
/// The following soring algorithm is running O(n^4) which we have to optimize somehow. 
/// </algorithm>
/// <param name="builds"></param>
/// <returns></returns>
/// <summary>
public IEnumerable<Entities.TestResult> RetrieveTestcasesFromSuite(string project, string buildNumber, int suiteId)
{
    SuiteSorting aps = new SuiteSorting();

    IBuilds build = TSBuilds.GetBuildByBuildNumber(project, buildNumber);

    List<Entities.TestResult> failedTestcases = new List<Entities.TestResult>();

    //Gets us a list of the testcase names from the suite number
    List<string> dataen = new List<string>();
    var testcaseSortingID = aps.GetTestcasesFromSuite(suiteId);
    foreach (var element in testcaseSortingID)
    {
        dataen.Add(GetTitleFromTestcaseID(element));
    }

    //For the build we select, we want to see...
    for (int i = 0; i < build.Count; i++)
    {
        ITestRuns testRuns = TS.Runs.TSRuns.GetTestRunByBuildUri(project, build.Value[i].Uri);
        // Show only test runs that have completed
        IEnumerable<TestRun> sortTestRuns = testRuns.Value.Where(p => p.State == TestState.Completed.ToString());

        //Foreach testrun in the build we want to see..
        foreach (ITestRun testRun in sortTestRuns)
        {
            ITestResults testResults = TS.Results.TSResults.GetListOfTestResultsByID(project, testRun.Id);
            // Show only test results that have not passed 
            IEnumerable<TestResult> sortedTestResults = testResults.Value.Where(p => p.Outcome != TestOutcome.Passed.ToString());

            //Foreach test result in each testrun we would like to...
            foreach (ITestResult testResult in sortedTestResults)
            {
                //Foreach testcase found within suites, compare it with all testcases looped from above..
                foreach (var element in dataen)
                {
                    //Foreach testcase in suite, compare with testcases from run.
                    if (element.Equals(testResult.TestCaseTitle))
                    {
                        failedTestcases.Add(new Entities.TestResult()
                        {
                            RunId = testResult.TestRun.Id,                      // The test Run ID
                            RunTitle = testResult.TestRun.Name,                 // The test run Title
                            TestResultId = testResult.Id,
                            Area = testResult.Project.Name,
                            ComputerName = testResult.ComputerName,
                            FailureType = testResult.FailureType,
                            ErrorMessage = testResult.ErrorMessage,
                            TestCaseId = testResult.TestCase.Id,
                            TestCaseTitle = testResult.TestCaseTitle,
                            TestRunId = testResult.TestRun.Id,
                            Reason = ReasonHandler.GiveReasonFromErrorMessage(testResult.ErrorMessage), //Reason
                            Match = ReasonHandler.CompareReasonWithErrorMessageOne(testResult.ErrorMessage),
                            ReasonCategorie = GiveCategorieFromReason(testResult.ErrorMessage, ReasonHandler.GiveReasonFromErrorMessage(testResult.ErrorMessage)), //Retrurns Categorie of reason                                                                                                                                                     // numberInRow = dataToReturn.Count, do we use it?
                            JiraIssueUrl = JiraCommunication.CreatejiraUrlFromReason(ReasonHandler.GiveReasonFromErrorMessage(testResult.ErrorMessage)),           //Creates the JiraIssueUrl
                            JiraKey = JiraCommunication.GetJiraKeyFromReason(ReasonHandler.GiveReasonFromErrorMessage(testResult.ErrorMessage)),
                            TestcaseTfsUrl = TfsHandler.GetTestcaseUrl(testResult.TestRun.Id.ToString(), testResult.Id.ToString()),
                            ResolutionStateId = testResult.ResolutionStateId
                        });
                    }
                }
            }
        }
    }
    return failedTestcases;
}

我认为您可以对最里面的两个循环执行以下操作并摆脱它们,因为您没有提供完整的代码,所以我没有进行任何测试:

var failedTestCases = sortedTestResults.Where(x => dataen.Contains(x.TestCaseTitle)).Select(testResult => new Entities.TestResult
{
                RunId = testResult.TestRun.Id,                      // The test Run ID
                RunTitle = testResult.TestRun.Name,
                TestResultId = testResult.Id,
                Area = testResult.Project.Name,
                // all other columns here ...
}).ToList();

正如我们在私人@KristoferMarEinarsson(我们是同事)中讨论的那样,您的性能下降来自外部调用,而不是算法/ CPU的性能问题。

GetBuildByBuildNumber

GetTestRunByBuildUri

GetListOfTestResultsByID

所有同步执行剩余查询,因此大大降低了算法速度。

由于循环中的每次迭代都不依赖于先前的迭代,因此可以使循环中的所有逻辑异步运行。 从理论上讲,这将使执行时间缩短到GetBuildByBuildNumber + GetTestRunByBuildUri + GetListOfTestResultsByID的最坏情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM