DataView - GetEnumerator
-
PIEBALDconsult wrote:
Try not to use foreach if you expect to break the iteration.
Thats the first time I hear this advice. It results in some little pretty ugly workarounds, doesn't it? No - I expect the coders to make their enumerators efficient and keep on enjoing the better design of foreach (if available).
Actually, it's the result of one of the tenets of iteration development. If you have to use a break statement (or god forbid a goto) to get out of a loop, you are using the wrong type of loop. Have a look at Code Complete by Steve McConnell to find more gems like this.
Deja View - the feeling that you've seen this post before.
-
PIEBALDconsult wrote:
Try not to use foreach if you expect to break the iteration.
Thats the first time I hear this advice. It results in some little pretty ugly workarounds, doesn't it? No - I expect the coders to make their enumerators efficient and keep on enjoing the better design of foreach (if available).
(Please note the joke icon.)
Mr.PoorEnglish wrote:
pretty ugly workarounds
Programs are like women: They can look good but not work. Or they can work but not look good. :-D
-
Actually, it's the result of one of the tenets of iteration development. If you have to use a break statement (or god forbid a goto) to get out of a loop, you are using the wrong type of loop. Have a look at Code Complete by Steve McConnell to find more gems like this.
Deja View - the feeling that you've seen this post before.
Hm, I'm real puzzled. Whenever I was searching anything in any Enumerable I used foreach. And broke the loop when I did find, what I wanted. Sample - how you would improve this little thing?
public TreeNode GetNodeByText(TreeNode Parent, string Txt) {
foreach (TreeNode Nd in Parent.Nodes) {
if (Nd.Text == Txt) return Nd;
}
return null;
}And how do you think is ICollection<T>.Contains() implemented in hundreds of classes? Steve McConnells Code Complete Loop - Chapter seems not to be available (for free, I mean).
modified on Friday, January 25, 2008 5:28:44 PM
-
Hm, I'm real puzzled. Whenever I was searching anything in any Enumerable I used foreach. And broke the loop when I did find, what I wanted. Sample - how you would improve this little thing?
public TreeNode GetNodeByText(TreeNode Parent, string Txt) {
foreach (TreeNode Nd in Parent.Nodes) {
if (Nd.Text == Txt) return Nd;
}
return null;
}And how do you think is ICollection<T>.Contains() implemented in hundreds of classes? Steve McConnells Code Complete Loop - Chapter seems not to be available (for free, I mean).
modified on Friday, January 25, 2008 5:28:44 PM
Well, try not to, but some times you may need to. Having said that, you may be able to iterate with the index of the nodes. Or, if you do more searching than adding/removing, you could use a Dictionary<string,TreeNode> to speed up the search.
-
Hm, I'm real puzzled. Whenever I was searching anything in any Enumerable I used foreach. And broke the loop when I did find, what I wanted. Sample - how you would improve this little thing?
public TreeNode GetNodeByText(TreeNode Parent, string Txt) {
foreach (TreeNode Nd in Parent.Nodes) {
if (Nd.Text == Txt) return Nd;
}
return null;
}And how do you think is ICollection<T>.Contains() implemented in hundreds of classes? Steve McConnells Code Complete Loop - Chapter seems not to be available (for free, I mean).
modified on Friday, January 25, 2008 5:28:44 PM
So - if somebody else writes bad code you think it's your duty to also write bad code? Just because somebody gives you a foreach doesn't mean that you have to use it in every case. Take a look at the alternatives such as the do/while loop.
Mr.PoorEnglish wrote:
Steve McConnells Code Complete Loop - Chapter seems not to be available (for free, I mean).
So do what others do and buy a copy of the book. You won't regret it.
Deja View - the feeling that you've seen this post before.
-
Hm, I'm real puzzled. Whenever I was searching anything in any Enumerable I used foreach. And broke the loop when I did find, what I wanted. Sample - how you would improve this little thing?
public TreeNode GetNodeByText(TreeNode Parent, string Txt) {
foreach (TreeNode Nd in Parent.Nodes) {
if (Nd.Text == Txt) return Nd;
}
return null;
}And how do you think is ICollection<T>.Contains() implemented in hundreds of classes? Steve McConnells Code Complete Loop - Chapter seems not to be available (for free, I mean).
modified on Friday, January 25, 2008 5:28:44 PM
lol, you are supposed to ignore using break/return completely so you have something to optimize later: Check out "The Speedup loop" http://thedailywtf.com/Articles/The-Speedup-Loop.aspx I could never bring myself to intentionally build a "speedup loop".
-
Hello folks! I did a little spy-out (with Reflector(c)) the DataView-Class. And found the following:
public IEnumerator GetEnumerator()
{
DataRowView[] array = new DataRowView[this.Count];
this.CopyTo(array, 0);
return array.GetEnumerator();
}Do I understand right: Each foreach-Initialisation it will copy all its Content to a new array, and return that arrays Enumerator?? And if I break the foreach-loop at second element all these DataRowViews came into live in vain?
Entirely depends on the cost of DataRowView - it may be a simple reference holder / adapter class whose creation is cheap, and CopyTo likely does only a flat copy (I don't know, though). An alternative might have to inject very complex code code to provide the same isolation level (e.g. allowing insertions and deletions applied to the underlying dataset during your enumeration). So this might be a WTF, or might not.
We are a big screwed up dysfunctional psychotic happy family - some more screwed up, others more happy, but everybody's psychotic joint venture definition of CP
blog: TDD - the Aha! | Linkify!| FoldWithUs! | sighist -
Entirely depends on the cost of DataRowView - it may be a simple reference holder / adapter class whose creation is cheap, and CopyTo likely does only a flat copy (I don't know, though). An alternative might have to inject very complex code code to provide the same isolation level (e.g. allowing insertions and deletions applied to the underlying dataset during your enumeration). So this might be a WTF, or might not.
We are a big screwed up dysfunctional psychotic happy family - some more screwed up, others more happy, but everybody's psychotic joint venture definition of CP
blog: TDD - the Aha! | Linkify!| FoldWithUs! | sighistpeterchen wrote:
Entirely depends on the cost of DataRowView - it may be a simple reference holder / adapter class whose creation is cheap, and CopyTo likely does only a flat copy (I don't know, though).
Hi peterchen! I did investigate that and found out, inside of DataView there is an "Index", managing a RBTree, and CopyTo takes the RBTree-Enumerator, who emits Integer - Indicees. These Indicees do reference the target-Datarow in a rowCache-array of the DataTable. To finally access the DataRowView there is a rowViewCache - Dictionary<DataRow, DataRowView> inside DataView. I built my own enumerator as wrapper of the RBTreee-Enumerator. This makes a enumeration-speed-up of DataRow of (only) 1 : 1.5 for 831 DataRows. To access only the first DataRow (then break foreach) the speed-up-factor is 1 : 4. So now I'm actually unshure, wether my selfmade-enumerator is worth-while.
-
peterchen wrote:
Entirely depends on the cost of DataRowView - it may be a simple reference holder / adapter class whose creation is cheap, and CopyTo likely does only a flat copy (I don't know, though).
Hi peterchen! I did investigate that and found out, inside of DataView there is an "Index", managing a RBTree, and CopyTo takes the RBTree-Enumerator, who emits Integer - Indicees. These Indicees do reference the target-Datarow in a rowCache-array of the DataTable. To finally access the DataRowView there is a rowViewCache - Dictionary<DataRow, DataRowView> inside DataView. I built my own enumerator as wrapper of the RBTreee-Enumerator. This makes a enumeration-speed-up of DataRow of (only) 1 : 1.5 for 831 DataRows. To access only the first DataRow (then break foreach) the speed-up-factor is 1 : 4. So now I'm actually unshure, wether my selfmade-enumerator is worth-while.
Interesting results - and good you investigated that! So indeed there are reasonable performance tradeoffs. In any case, I wouldn't expect the enumerator to be optimized for a "break after first". That's a very uncommon scenario - and if you run into it frequently, and it hits your performance, you could always optimize by "get first, test, then enumerate" on the caller side.
We are a big screwed up dysfunctional psychotic happy family - some more screwed up, others more happy, but everybody's psychotic joint venture definition of CP
blog: TDD - the Aha! | Linkify!| FoldWithUs! | sighist -
(Please note the joke icon.)
Mr.PoorEnglish wrote:
pretty ugly workarounds
Programs are like women: They can look good but not work. Or they can work but not look good. :-D
PIEBALDconsult wrote:
Or they can work but not look good.
That's me ;P
--> Applied Knowledge Group - linking the knowledge of people