Speicherverbrauch Rekursion
- 
					
					
					
					
 Hallo Leute, ich mach gerade bisschen Memoryprofiler mit VS2012:) 
 Und da is mir aufgefallen, dass folgende Rekursion rel. viel speicher frist:public IEnumerable<object> GetFlatChildrenOfType(Type type) { return _children .Where(it => type.IsAssignableFrom(it.GetType())) .Cast<object>() .Concat(_children .SelectMany(it => it.GetFlatChildrenOfType(type))); }Jetzt mal allg. gefragt, wie könnte ich diese LINQ anweisung speichersparender machen? geht das überhaupt  Grüße  
 
- 
					
					
					
					
 Rekursives SelectMany()sollte man immer vermeiden, das hat miserable Speicher- und Performancecharakteristik. Vgl. die Erörterung in [1] (da gehts um rekursive Iteratoren, aber das Problem ist dasselbe, weilSelectMany()mit Iteratoren implementiert ist).Du kannst dir eine Hilfsfunktion wie folgt bauen: public static class EnumerableHelper { public static IEnumerable<T> FlattenRecursive<T>(T item, Func<T, IEnumerable<T>> subitemSelector) { return Flatten(new[] { item }, subitemSelector); } public static IEnumerable<T> FlattenRecursive<T>(IEnumerable<T> items, Func<T, IEnumerable<T>> subitemSelector) { // TODO: implement } }Das wäre eine prima Übung für eine Einstiegsvorlesung in Algorithmen und Datenstrukturen  Bonuspunkte gibt es, wenn man die gewünschte Rekursionsabfolge wählen kann: Bonuspunkte gibt es, wenn man die gewünschte Rekursionsabfolge wählen kann:public enum TreeRecursionMode { DepthFirst, BreadthFirst }Am leichtesten ist die Implementation übrigens in F#, weil du da yield!benutzen kannst, was dir genau diese Arbeit abnimmt. In C# mußt du von Hand einen Stack von Enumeratoren verwalten.Wenn du über FlattenRecursive()verfügst, kannst du deine Funktion so implementieren:public IEnumerable<object> GetFlatChildrenOfType(Type type) { return EnumerableHelper.FlattenRecursive(this, obj => obj._children.Where(child => type.IsAssignableFrom(child.GetType())); }Wie du übrigens siehst, ist das Cast<object>()ist überflüssig, weilIEnumerable<T>kovariant inTist. Überhaupt wird deine Funktion viel schöner, wenn du sie generisch machst:public IEnumerable<T> GetFlatChildrenOfType<T>() { return EnumerableHelper.FlattenRecursive(this, obj => obj._children.OfType<T>()); }
 
- 
					
					
					
					
 Danke für deine erleuterungen, die Funktion würde ich gerne generisch machen, aber die schnittstelle sieht leider die variatne mit dem Typ argument vor! In C# kanst du doch auch "yield return" machen!? Dannn profile ich mal deine implementation:) 
 
- 
					
					
					
					
 NullBockException schrieb: In C# kanst du doch auch "yield return" machen!? Ja. Und? NullBockException schrieb: Dannn profile ich mal deine implementation:) Meine Implementation kennst du doch gar nicht. 
 
- 
					
					
					
					
 Meine Implementation kennst du doch gar nicht. Deinen Helper! Ja. Und? weil du von F# geredet hast.. 
 
- 
					
					
					
					
 NullBockException schrieb: Meine Implementation kennst du doch gar nicht. Deinen Helper! Dir ist nicht aufgefallen, daß da "TODO: implement" vermerkt ist?  Die Funktion ist nicht ganz trivial, aber wenn du ein bißchen nachdenkst, kommst du bestimmt selbst drauf, wie man die baut. Den entscheidenden Hinweis (Enumerator-Stack) habe ich dir schon gegeben. NullBockException schrieb: Ja. Und? weil du von F# geredet hast.. Achso. yield returnin C# entsprichtyieldin F#, aberyield!ist ein bißchen anders, das entspricht dem hypothetischenyield foreach[1], das es in C# leider noch nicht gibt.[1] http://blogs.msdn.com/b/wesdyer/archive/2007/03/23/all-about-iterators.aspx 
 
- 
					
					
					
					
 Dir ist nicht aufgefallen, daß da "TODO: implement" vermerkt ist?  Die Funktion ist nicht ganz trivial, aber wenn du ein bißchen nachdenkst, kommst du bestimmt selbst drauf, wie man die baut. Den entscheidenden Hinweis (Enumerator-Stack) habe ich dir schon gegeben. Dein Pattern .. ja hab ich bemerkt:) Bist du Mathematiker?? Im dichten Nebel verliert ein Ballonfahrer die Orientierung. Er lässt seinen Ballon langsam ab, bis er am Boden einen Menschen sieht, und ruft herab: "Wo bin ich hier?" Daraufhin grübelt der Passant eine Weile und antwortet: "Im Ballon!" Er überlegt lange. 
 Seine Antwort ist absolut korrekt.
 Seine Aussage ist zu nichts zu gebrauchen.:p kleiner scherz 
 
- 
					
					
					
					
 Selber Schuld wenn du C# verwendest (auch ein kleiner Scherz). 
 
- 
					
					
					
					
 ich denke das problem hat nix mit der sprache zu tun^^ 