Алгоритм оптимизации - c # - PullRequest
0 голосов
/ 25 июня 2018

У меня есть этот алгоритм, над которым я работал в течение некоторого времени, но моя проблема в том, что он довольно медленный.Мне придется как-то оптимизировать его, но я нахожу это немного сложным.Текущая скорость равна O (n ^ 4) с некоторым дополнительным выполнением циклов for.

Что я пытаюсь достичь?

У меня есть много тестовых случаев, хранящихся в «разделе выполнения», а некоторые тестовые случаи хранятся в «разделе набора».Я хотел бы сравнить тестовые наборы, чтобы увидеть, какие тестовые наборы потерпели неудачу в «разделе комплекта».Но чтобы получить все тестовые наборы failen, мне сначала нужно пройтись по циклу сборки, чтобы перейти к тестовым прогонам, затем пройти через тестовые прогоны, чтобы добраться до тестовых случаев, а затем я сравниваю «тестовые разделы секции выполнения» с «тестовыми примерами секции комплекта» в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;
}

Ответы [ 2 ]

0 голосов
/ 26 июня 2018

Как мы обсуждали в частном порядке @KristoferMarEinarsson (Мы коллеги), ваш прирост производительности происходит от внешних вызовов и не является проблемой производительности вашего алгоритма / процессора как такового.

GetBuildByBuildNumber

GetTestRunByBuildUri

GetListOfTestResultsByID

Все ли запросы выполняются синхронно и поэтому сильно тормозят ваш алгоритм.

Поскольку каждая итерация в циклах не зависит от предыдущей, вся логика в ваших циклах может выполняться асинхронно. Теоретически это привело бы к сокращению времени выполнения до наихудшего случая GetBuildByBuildNumber + GetTestRunByBuildUri + GetListOfTestResultsByID.

0 голосов
/ 25 июня 2018

Я думаю, что вы можете сделать что-то подобное ниже для двух самых внутренних циклов и избавиться от них, я ничего не проверял, так как вы не предоставили полный код:

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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...