2009-07-06 6 views
1

Я работаю с WPF, и я разрабатываю сложный пользовательский контроль, состоящий из дерева с богатой функциональностью и т. Д. Для этого я использовал шаблон проектирования View-Model, поскольку некоторые операции не могли быть достигнуты напрямую в WPF. Поэтому я беру IHierarchyItem (который является узлом и передать его в этот конструктор, чтобы создать структуру дерева)Обход дерева без рекурсивного/стекового использования (C#)?

private IHierarchyItemViewModel(IHierarchyItem hierarchyItem, IHierarchyItemViewModel parent) 
     { 
      this.hierarchyItem = hierarchyItem; 
      this.parent = parent;  

      List<IHierarchyItemViewModel> l = new List<IHierarchyItemViewModel>(); 
      foreach (IHierarchyItem item in hierarchyItem.Children) 
      { 
       l.Add(new IHierarchyItemViewModel(item, this)); 
      } 
      children = new ReadOnlyCollection<IHierarchyItemViewModel>(l); 
     } 

Проблема заключается в том, что этот конструктор занимает около 3 секунд !! для 200 предметов на моем двухъядерном процессоре. Я делаю anythig неправильный или рекурсивный вызов конструктора, это медленно? Большое спасибо!

+0

Хорошо, все вышеописанное. Проблема была в иерархии. Дети продолжались слишком долго. –

ответ

3

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

Было бы полезно выполнить некоторые простые профилирования для вашего конструктора. Используя одно из предложений от: http://en.csharp-online.net/Measure_execution_time, вы можете указать, сколько времени занимает каждая часть.

Существует вероятность того, что одна деталь, в частности, занимает много времени. В любом случае, это может помочь вам сузить место, где вы действительно проводите время.

+0

Спасибо, я попробую этот фрагмент. Возможно, вы правы, это не может занять больше времени, проблема может быть где-то в определенном пункте. –

+0

int this line: foreach (элемент IHierarchyItem в файле hierarchyItem.Children) hierarchyItem.Children занимает слишком много времени. –

4

OK Я нашел нерекурсивную версию самостоятельно, хотя она использует стек. Он проходит по всему дереву:

Stack<MyItem> stack = new Stack<MyItem>(); 

stack.Push(root); 

while (stack.Count > 0) 
{ 
    MyItem taken = stack.Pop(); 

    foreach (MyItem child in taken.Children)     
     stack.Push(MyItem);      

} 
+0

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