tag:blogger.com,1999:blog-33753991.post2162934823332334039..comments2023-09-01T06:00:23.693-07:00Comments on Geek Goddess: Fun With DataSetsBonniehttp://www.blogger.com/profile/11241425687786973525noreply@blogger.comBlogger35125tag:blogger.com,1999:blog-33753991.post-59370269764585722762016-09-29T07:15:16.796-07:002016-09-29T07:15:16.796-07:00That's not going to be an easy question to ans...That's not going to be an easy question to answer here because there's probably going to be too much code you'd have to post to show me what you've got and then I'd have to post some code back to you. As you can see, if you've looked at some of the comments here, there is no formatting, so the code is hard to read.<br /><br />And, your question really has nothing to do with this blog post about DataSets. So, I suggest that you post your question on the MSDN forums here: <br /><br />https://social.msdn.microsoft.com/Forums/windows/en-US/home?forum=winformsdatacontrols<br /><br />And then come back to these comments and post a link to your MSDN question so I can help you there (and you just might get help from other people too). <br /><br />Oh, wait a minute, I see that you *did* post on the forums (https://social.msdn.microsoft.com/Forums/windows/en-US/d66f7162-02b3-42e5-8135-784f5a373019/convert-checkbox-into-textboxmessage-in-datagridview-directly-from-sql-while-running-the-program?forum=winformsdatacontrols) ... I'll go take a look at it.Bonniehttps://www.blogger.com/profile/11241425687786973525noreply@blogger.comtag:blogger.com,1999:blog-33753991.post-79275658206529347142016-09-29T05:21:39.142-07:002016-09-29T05:21:39.142-07:00HELLO BONNIE I DON'T KNOW HOW TO POST NEW Q? H...HELLO BONNIE I DON'T KNOW HOW TO POST NEW Q? HERE so sorry for everything<br />can i change checkbox into textbox in datagridview ??? i have sql table having one column name as status & its data type is bit when i run the program it is showing textbox's i want to change it can u help me ..?? thanks in advance..JYOTHIhttps://www.blogger.com/profile/06522164646509911828noreply@blogger.comtag:blogger.com,1999:blog-33753991.post-32077974871212413112016-07-05T08:46:33.336-07:002016-07-05T08:46:33.336-07:00I fixed it Jon. Thanks! I think that what had happ...I fixed it Jon. Thanks! I think that what had happened was that I must have copy/pasted from the wrong code snippet and didn't even notice it! I guess I must have been in a hurry that day. =0(Bonniehttps://www.blogger.com/profile/11241425687786973525noreply@blogger.comtag:blogger.com,1999:blog-33753991.post-48659450777722378622016-07-01T09:42:16.665-07:002016-07-01T09:42:16.665-07:00Mt. Olympus ... that's funny! ;0) But, you&...Mt. Olympus ... that's funny! ;0) But, you're right, Jon! I never did update that to a foreach. Guess I should do that! Thanks for catching that ...Bonniehttps://www.blogger.com/profile/11241425687786973525noreply@blogger.comtag:blogger.com,1999:blog-33753991.post-31174424878844387372016-07-01T00:42:35.466-07:002016-07-01T00:42:35.466-07:00Err, just a minor point Bonnie, maybe you have bee...Err, just a minor point Bonnie, maybe you have been spending too long on Mt Olympus, but the new version of your loop still uses 'for' not 'foreach'!<br /><br />JonAnonymousnoreply@blogger.comtag:blogger.com,1999:blog-33753991.post-66396912581623099422015-12-25T16:29:00.243-08:002015-12-25T16:29:00.243-08:00Oh, *that* Count ... sorry, I didn't catch tha...Oh, *that* Count ... sorry, I didn't catch that that's what you meant. Must've been because it was too early (before I had my coffee!!!) ... I'll play with it again later today and see what happens.Bonniehttps://www.blogger.com/profile/11241425687786973525noreply@blogger.comtag:blogger.com,1999:blog-33753991.post-50112879207824673822015-12-25T15:32:49.060-08:002015-12-25T15:32:49.060-08:00Both the loops fetch Count every time round the lo...Both the loops fetch Count every time round the loop, e.g.:<br /><br />for (int nRow = 0; nRow < this.dsGlobal.Tables[nTable].Rows.Count; nRow++)<br /><br />Now I haven't looked at what kind of collection 'Rows' is but when you access the Count member it calls a get() function, which might have to work out the count painfully every time e.g. if it is a linked list. So I was just suggesting something like:<br /><br />int count = this.dsGlobal.Tables[nTable].Rows.Count;<br />for (int nRow = 0; nRow < count; nRow++)<br /><br />It may not make any difference but it removes any possibility of criticism from anyone who reads your new blog :-)Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-33753991.post-18856077872285876812015-12-25T08:54:15.949-08:002015-12-25T08:54:15.949-08:00It didn't really make much difference. My orig...It didn't really make much difference. My original for loop (I posted the numbers), tended toward 8 times slower, and the new test that you suggested tends towards 7 times slower. Both sets of for loops (the original and the one using a row collection variable to iterate through), took between 700 - 800 milliseconds, with the first in the high 700's and the second in the low 700's. <br /> <br />You said:<br />>>I would like to see the row count worked out outside the loop too since there are two calls involved in calculating it.<<<br /> <br />I don't know what you mean by that. There is no counting going on in the loops, there's nothing like that there in the code I posted. The data is retrieved once (and its row count displayed at the time, so only once), and that happens before the button is ever clicked to start timing the two loops.<br />Bonniehttps://www.blogger.com/profile/11241425687786973525noreply@blogger.comtag:blogger.com,1999:blog-33753991.post-56088218646069467892015-12-24T14:27:47.859-08:002015-12-24T14:27:47.859-08:00We shall see ... but I would like to see the row c...We shall see ... but I would like to see the row count worked out outside the loop too since there are two calls involved in calculating it.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-33753991.post-6373936336538759282015-12-24T09:03:23.503-08:002015-12-24T09:03:23.503-08:00I bet it wouldn't matter, Jon ... but I'll...I bet it wouldn't matter, Jon ... but I'll try it later today (with my 2 million rows) and let you know!Bonniehttps://www.blogger.com/profile/11241425687786973525noreply@blogger.comtag:blogger.com,1999:blog-33753991.post-40981340698233683962015-12-24T08:58:57.189-08:002015-12-24T08:58:57.189-08:00OK, so you must have mangled this sentence:
> w...OK, so you must have mangled this sentence:<br />> with foreach taking around 800 milliseconds and for taking around 100 milliseconds<br /><br />Great, you *are* fetching the item in the for loop so ignore my previous IMHO! I suspect the problem with the for loop is that the inner loop is having to evaluate a complicated expression to get the Rows collection 2 million times so I wonder how different it would be if you coded the for loop like this (changes in bold):<br /><br />for (int nTable = 0; nTable < this.dsGlobal.Tables.Count; nTable++)<br />{<br /><b>DataRowCollection rows = this.dsGlobal.Tables[nTable].Rows;</b><br />for (int nRow = 0; nRow < <b>rows</b>.Count; nRow++)<br />{<br />if (<b>rows</b>[nRow].HasVersion(DataRowVersion.Proposed))<br />{<br /><b>rows</b>[nRow].EndEdit();<br />}<br />}<br />}<br />Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-33753991.post-37925545295581098192015-12-24T08:09:27.909-08:002015-12-24T08:09:27.909-08:00This comment has been removed by the author.Bonniehttps://www.blogger.com/profile/11241425687786973525noreply@blogger.comtag:blogger.com,1999:blog-33753991.post-3364963268608373082015-12-24T07:59:03.662-08:002015-12-24T07:59:03.662-08:00Jon, nope nothing mangled there! The foreach is 8 ...Jon, nope nothing mangled there! The foreach is 8 times faster! Surprised the hell out of me too! I didn't have actual data with 2 million rows. I grabbed a few thousand from a database table, then copied and merged it together in a loop about 7 times. Since there weren't any PKs set, the merge simply appended rows, resulting in 2 million.<br /><br />DataTable dt;<br />for (int i = 0; i < 7; i++)<br />{<br /> dt = this.dsGlobal.Tables[0].Copy();<br /> this.dsGlobal.Tables[0].Merge(dt);<br />}<br /><br />Here's the code I ran to test the timing. It runs from a button click, toggling between timing the for one time, the foreach the next time. Just keep clicking the button:<br /><br />Stopwatch oWatch = new Stopwatch();<br />if (this.Toggle)<br />{<br /> // Time the for loop<br /> this.Toggle = false;<br /> oWatch.Start();<br /> for (int nTable = 0; nTable < this.dsGlobal.Tables.Count; nTable++)<br /> {<br /> for (int nRow = 0; nRow < this.dsGlobal.Tables[nTable].Rows.Count; nRow++)<br /> {<br /> if (this.dsGlobal.Tables[nTable].Rows[nRow].HasVersion(DataRowVersion.Proposed))<br /> {<br /> this.dsGlobal.Tables[nTable].Rows[nRow].EndEdit();<br /> }<br /> }<br /> }<br /> oWatch.Stop();<br /> this.richTextBox1.Text += string.Format("For in {0} milliseconds\r\n", oWatch.ElapsedMilliseconds);<br />}<br />else<br />{<br /> // Time the foreach loop<br /> this.Toggle = true;<br /> oWatch.Start();<br /> foreach (DataTable dt in this.dsGlobal.Tables)<br /> foreach (DataRow row in dt.Rows)<br /> if (row.HasVersion(DataRowVersion.Proposed))<br /> row.EndEdit();<br /> oWatch.Stop();<br /> this.richTextBox1.Text += string.Format("Foreach in {0} milliseconds\r\n", oWatch.ElapsedMilliseconds);<br />}<br /><br />Oh, and here's the results:<br /><br />Time using 1,943,936 Rows<br />For in 832 milliseconds<br />Foreach in 101 milliseconds<br />For in 768 milliseconds<br />Foreach in 102 milliseconds<br />For in 772 milliseconds<br />Foreach in 102 milliseconds<br />For in 858 milliseconds<br />Foreach in 103 milliseconds<br />For in 757 milliseconds<br />Foreach in 132 milliseconds<br />For in 750 milliseconds<br />Foreach in 102 milliseconds<br />Bonniehttps://www.blogger.com/profile/11241425687786973525noreply@blogger.comtag:blogger.com,1999:blog-33753991.post-28426873482701476992015-12-24T05:30:23.285-08:002015-12-24T05:30:23.285-08:00Bonnie, I think you have mangled a sentence: you s...Bonnie, I think you have mangled a sentence: you say "It turns out that foreach is roughly 8 times faster than for" but I think you mean the other way around?<br /><br />IMHO I think you ought to make the for loop fetch the item of interest because you wouldn't be doing the loop unless you were going to access said item and you get it for free with foreach. Perhaps do the timings for both cases?<br /><br />Wish I had a DataSet with 2 million rows ... not :-)<br /><br />Merry Xmas<br /><br />JonAnonymousnoreply@blogger.comtag:blogger.com,1999:blog-33753991.post-23242661655563624962015-12-23T08:32:00.815-08:002015-12-23T08:32:00.815-08:00Hi Jon, I did a similar test, but did not set any ...Hi Jon, I did a similar test, but did not set any object in the for loop, because the original loops did not do that either. <br />It turns out that foreach is roughly 8 times faster than for. I did a test with a DataSet that had almost 2 million rows (1,943,936 to be exact). <br />Each iteration I did was almost identical, time-wise, with foreach taking around 800 milliseconds and for taking around 100 milliseconds. I'm going to update this blog post with this and maybe even write another blog post just on this topic.<br />I even changed the Target Framework for the assembly, to be able to test with 2.0. Even way back then, foreach was still faster. I couldn't set the Target Framework to 1.1 (there was no option for that), so I couldn't test that ... but, I started out back in 2002 using 1.1, so perhaps my observations that for was faster than foreach goes all the way back to then! Wow!Bonniehttps://www.blogger.com/profile/11241425687786973525noreply@blogger.comtag:blogger.com,1999:blog-33753991.post-49603642888006447962015-12-22T02:20:38.160-08:002015-12-22T02:20:38.160-08:00I looked at the disassembly and no, the assignment...I looked at the disassembly and no, the assignment to 'item' in the for loop was not optimized away.<br /><br />JonAnonymousnoreply@blogger.comtag:blogger.com,1999:blog-33753991.post-62207074072069746372015-12-22T02:07:13.036-08:002015-12-22T02:07:13.036-08:00I had a bit of time on my hands so I timed the fol...I had a bit of time on my hands so I timed the following loops. 'reqTable' is a DataTable with 19 rows and 3 columns, so admittedly not a large sample:<br /><br />1.<br />foreach (DataRow row in reqTable.Rows)<br /> foreach (object item in row.ItemArray)<br /> counter++;<br /><br />2.<br />for (int rowIndex = 0; rowIndex < reqTable.Rows.Count; rowIndex++)<br />{<br /> DataRow row = reqTable.Rows[rowIndex];<br /> for (int col = 0; col < row.ItemArray.Length; col++)<br /> {<br /> object item = row.ItemArray[col];<br /> counter++;<br /> }<br />}<br /><br />Note that I fetch the object of interest manually in the for loop case because the foreach loop does that for me.<br /><br />Here are my timings for 4 consecutive runs, release build (so it's possible my fetch of 'item' was optimized out), measured in usec (using QueryPerformanceCounter()):<br /><br />foreach: 62.4, 3.4, 3.0, 3.4<br /> for: 17.1, 10.7, 9.8, 12.4<br /><br />Conclusion: foreach is considerably slower the first time but considerably faster all the other times! Go figure...<br /><br />JonAnonymousnoreply@blogger.comtag:blogger.com,1999:blog-33753991.post-2442112476551113052015-12-16T08:07:49.921-08:002015-12-16T08:07:49.921-08:00No, sorry, I meant to say that whenever a DataTabl...No, sorry, I meant to say that whenever a DataTable is modified using one of the controls bound to it (well, actually to a DataView mapped onto a single row of the table) the change is visible in the DataTable's DataRow but GetChanges() returns null unless I run your code.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-33753991.post-15255974139208378962015-12-16T07:15:02.269-08:002015-12-16T07:15:02.269-08:00Hi Jon, Every row in your entire DataSet is in the...Hi Jon, Every row in your entire DataSet is in the Proposed version? Wow, I haven't encountered that before. The only thing I can think of is that perhaps you have some code somewhere that goes through each row and does something, like adds a default value.<br /><br />And you've got a good point about using foreach, from a readability standpoint. Early in the days of .NET, I'm pretty sure that a "for loop" was several orders of magnitude faster than a "foreach loop". I wrote this blog post in 2009, but the actual code goes back quite a few years before that. The compiler nowadays may generate code now where the performance is identical. I don't know, I haven't tested that lately. But maybe I'll give it a test sometime today.Bonniehttps://www.blogger.com/profile/11241425687786973525noreply@blogger.comtag:blogger.com,1999:blog-33753991.post-17036389856996660462015-12-16T02:47:32.822-08:002015-12-16T02:47:32.822-08:00In my case it *always* seems to happen i.e. HasVer...In my case it *always* seems to happen i.e. HasVersion(Proposed) check is always true. I can't help thinking I am missing something that would cause the entire DataSet to change to the Current state. But for now, I am more than happy to use your excellent fix, thanks a million! Talking about proposals (no, not that one) can I suggest an improvement to your code? These loops are much simpler using 'foreach':<br /><br /> foreach (DataTable table in ds.Tables)<br /> {<br /> foreach (DataRow row in table.Rows)<br /> {<br /> if (row.HasVersionDataRowVersion.Proposed))<br /> {<br /> row.EndEdit();<br /> }<br /> }<br /> }<br /><br />(sorry about the non-formatting, I can't seem to get much HTML to work)<br /><br />Jon PryceAnonymousnoreply@blogger.comtag:blogger.com,1999:blog-33753991.post-8576250679860907532015-01-23T21:53:40.083-08:002015-01-23T21:53:40.083-08:00You're welcome, Bruce! I'm glad I could he...You're welcome, Bruce! I'm glad I could help! =0)Bonniehttps://www.blogger.com/profile/11241425687786973525noreply@blogger.comtag:blogger.com,1999:blog-33753991.post-20939291942535047942015-01-23T21:48:31.895-08:002015-01-23T21:48:31.895-08:00After a day looking and trying, this worked!!!!!
T...After a day looking and trying, this worked!!!!!<br />The concept is simple, if only I had known.....godess is an apt description<br />Many thaks<br />Bruce C NZbruce caldwellhttp://www.taurangacoastguard.co.nznoreply@blogger.comtag:blogger.com,1999:blog-33753991.post-33136631489488107862013-03-01T09:47:33.716-08:002013-03-01T09:47:33.716-08:00well they(my users) seem happy enough with it, so ...well they(my users) seem happy enough with it, so thaks againAnonymousnoreply@blogger.comtag:blogger.com,1999:blog-33753991.post-20874006629381888122013-02-28T11:00:59.532-08:002013-02-28T11:00:59.532-08:00Hopefully, this should continue to work for you. I...Hopefully, this should continue to work for you. If it does, I'm glad I could help! If it doesn't, let me know ...Bonniehttps://www.blogger.com/profile/11241425687786973525noreply@blogger.comtag:blogger.com,1999:blog-33753991.post-2126734656260521162013-02-28T10:51:17.526-08:002013-02-28T10:51:17.526-08:00struggled for a while with DataGridView changes th...struggled for a while with DataGridView changes this seems to work very nicely thanks<br />(just a bit cautious because nothing else I have tried has worked)Anonymousnoreply@blogger.com