Akhil Jain Ответов: 3

Список, содержащий еще 2 списка, работает медленно в цикле, могу ли я использовать поток, чтобы сделать это быстрее?


Это мой код, в котором список содержит еще 2 списка, где WorkItem коллекция содержит большое количество записей, таких как 7000, что занимает 10 минут. Есть ли какой-нибудь способ сделать это быстрее и в случае, если он решает тип workItem, если это ошибка, задача или элемент невыполненной работы продукта? Пожалуйста, скажите мне, как сделать цикл быстрее. Это займет 10 минут, чтобы зациклить 7000 записей можем ли мы использовать резьбу, чтобы сделать это быстрее?
var workItemList = new List<WorkItemViewModel>();

           for (int i = 0; i < workItemCollection.Count; i++)
           {
               var workItem = workItemCollection[i];

               if (workItem.Type.Name == "Product Backlog Item")
               {
                   var model = new WorkItemViewModel()
                   {


                       FID = (workItem.WorkItemLinks.Count > 0) ? ((workItem.WorkItemLinks[0].LinkTypeEnd.Name.ToString() != "Child") ? workItem.WorkItemLinks[0].TargetId : 0) : 0,

                       ID = workItem.Id,
                       Name = workItem.Title,
                       State = workItem.State,

                       priorty = Convert.ToInt32(workItem.Fields["Priority"].Value),
                       //   Size =(int) workItem.Fields["Size"].Value ,
                       Size = Convert.ToInt32(workItem.Fields["Effort"].Value),

                       StoryPoints = Convert.ToInt32(workItem.Fields["Story Points"].Value),
                       DoneStatus = workItem.Fields["Done Status"].Value.ToString(),
                       StoryOwner = workItem.Fields["Story Owner"].Value.ToString(),
                       Assignedto = workItem.Fields["Assigned To"].Value.ToString(),
                       StoryAuthor = workItem.Fields["Story Author"].Value.ToString(),
                       IterationPath = workItem.IterationPath
                   };

                   workItemList.Add(model);
               }
               else
               {
                   switch (workItem.Type.Name)
                   {
                       case "Task":
                           var task = new TFSTask()
                           {
                               Storyid = (workItem.WorkItemLinks.Count > 0) ? workItem.WorkItemLinks[0].TargetId : 0,
                               ID = workItem.Id,
                               name = workItem.Title,
                               //activity = workItem.Fields["MyCompany.Activity"].Value.ToString(),
                               //start = (DateTime?)workItem.Fields["MyCompany.ActivityStart"].Value,
                               //due = (DateTime?)workItem.Fields["MyCompany.ActivityFinish"].Value,
                               status = workItem.State,
                               IterationPath = workItem.IterationPath,
                               Assignedto = workItem.Fields["Assigned To"].Value.ToString(),

                               priorty = Convert.ToInt32(workItem.Fields["Priority"].Value),
                               effort = Convert.ToInt32(workItem.Fields["effort"].Value),
                               Completed = Convert.ToInt32(workItem.Fields["Completed"].Value)

                           };
                           if (task.Storyid != 0)
                           {
                               workItemList.Last().Tasks.Add(task);
                           }


                           break;
                       case "Bug":
                           var bug = new TFSIssue()
                           {
                               Storyid = (workItem.WorkItemLinks.Count > 0) ? workItem.WorkItemLinks[0].TargetId : 0,
                               ID = workItem.Id,
                               Name = workItem.Title,
                               //start = (DateTime?)workItem.Fields["MyCompany.ActivityStart"].Value,
                               //due = (DateTime?)workItem.Fields["MyCompany.ActivityFinish"].Value,
                               State = workItem.State,
                               IterationPath = workItem.IterationPath,
                               Assignedto = workItem.Fields["Assigned To"].Value.ToString(),

                               priorty = Convert.ToInt32(workItem.Fields["Priority"].Value),
                               effort = Convert.ToInt32(workItem.Fields["effort"].Value),
                               // Completed = Convert.ToInt32(workItem.Fields["Completed"].Value)
                           };
                           if (bug.Storyid != 0)
                           {
                               workItemList.Last().Issues.Add(bug);
                           }
                           break;



                       default:
                           break;
                   }
               }
           }

public class WorkItemViewModel
   {
       public string Name { get; set; }
       public int ID { get; set; }

       public string State { get; set; }
       // public DateTime? due { get; set; }
       public int priorty { get; set; }
       public int Size { get; set; }
       //  public int effort { get; set; }
       public int StoryPoints { get; set; }
       public string DoneStatus { get; set; }
       public string StoryOwner { get; set; }
       public string Assignedto { get; set; }
       public string StoryAuthor { get; set; }
       public string IterationPath { get; set; }
       public int FID { get; set; }
       public List<TFSIssue> Issues { get; set; }
       public List<TFSTask> Tasks { get; set; }

       public WorkItemViewModel()  // Added a public constructor
       {
           Issues = new List<TFSIssue>();
           Tasks = new List<TFSTask>();

       }

   }


Что я уже пробовал:

Список, содержащий еще 2 списка, работает медленно в цикле, могу ли я использовать поток, чтобы сделать это быстрее?

BillWoodruff

Ваша первая цель может состоять в том, чтобы попытаться уменьшить количество записей, которые вы обрабатываете, фильтруя то, что вы извлекаете из своей базы данных.

Akhil Jain

это невозможно !!

Richard MacCutchan

Нарезание резьбы не поможет, пока вы не устраните проблемы, указанные ниже. И даже тогда нет никакой гарантии, что он будет работать быстрее.

3 Ответов

Рейтинг:
2

phil.o

(workItem.WorkItemLinks[0].LinkTypeEnd.Name.ToString()
Почему звонит ToString() на члене, который уже является string Этот вопрос также относится и к другим ToString() обычаи в вашем коде.

Size = Convert.ToInt32(workItem.Fields["Effort"].Value)
Convert класс показывает действительно низкую производительность по сравнению со встроенными функциями синтаксического анализа. Всегда использовать Parse или TryParse методы, когда вы хотите получить целочисленное значение из строки. Например, приведенный выше фрагмент кода можно было бы заменить на
Size = int.Parse(workItem.Fields["Effort"].Value)

Кроме того, если Value уже был бы типаж int, не было бы никакой необходимости в разборе вообще. Не зная определения вашего WorkItemViewModel класс, это всего лишь предположение.

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

Только мои 2 цента. Надеюсь, это поможет.


Akhil Jain

поставили секундомер до и после петли и он показывает 10 минут

Akhil Jain

не могу ли я использовать потоковую обработку, это просто уменьшит 2 минуты (до строки и значения)!!

phil.o

Да, ты можешь. Но вы должны принять хорошие практики в первую очередь и избегать выполнения ненужных вызовов и низкоэффективных классов, таких как Convert.
8 мин вместо 10-это уже 20% улучшение производительности, то есть не пренебрежимо мало.

phil.o

Более того, имея более глубокий взгляд на ваш код, зачем использовать workItem.Fields["Priority"].Value когда вы могли бы писать workItem.priorty? (опечатка, унаследованная от кода, который вы показали)

Akhil Jain

это значение там в полях, а не workItem.priorty

BillWoodruff

+5

Рейтинг:
2

BillWoodruff

Если вы серьезно относитесь к пониманию производительности времени в .NET, я предлагаю вам научиться использовать один из этих инструментов с открытым исходным кодом: BenchmarkDotNet (то, что я использую) [^], или AppMetrics [^Делая это, вы станете лучшим программистом. Скотт Хансельман писал о бенчмарке в 2016 году: [^Оба эти проекта активно поддерживаются.

Без понимания структуры базы данных здесь наша способность помочь вам, имхо, ограничена видами (превосходных) предложений, которые опубликовал phil.o.

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

Взгляните на эту статью CP для получения общего обзора: [^]

Изучите функции в Linq, которые могут быть актуальны: [^]


phil.o

Спасибо, Билл. Хорошие советы тоже.

Рейтинг:
1

Patrice T

Я не вижу ничего очевидного.
Вам нужно понять, где и как тратится время, инструментом выбора является профилировщик.
Профилирование (компьютерное программирование) - Википедия[^]
Список инструментов анализа производительности - Википедия[^]

[Обновление]

Цитата:
поставили секундомер до и после петли и он показывает 10 минут

"Понимание того, как тратится время" означает измерение времени, затрачиваемого на каждую строку кода, чтобы понять, какая из них потребляет больше всего времени.


Akhil Jain

разве я не могу использовать резьбу ?

Patrice T

Ответ зависит от того, как будет потрачено время.

Akhil Jain

поставили секундомер до и после петли и он показывает 10 минут