Thanks for all the good comments. The only reason I go to an object at the start is to set default values for each column - if the incoming data doesn't contain that columns field. I'll take a hard look at what I've got and see where I can reduce the loops and conversions.
Thanks again. John --- In [email protected], "Alex Harui" <[EMAIL PROTECTED]> wrote: > > Well, I wouldn't use the term "horrible", but yeah, what you're doing > isn't optimal. Let me try to illustrate: > > > > A bunch of xml nodes come over the wire. Your resultFormat is "object" > so the service is going to do: > > > > for (i= 0; i < numNodes; i++) > > <convert to object> > > > > Then dispatch the result event. Your code then checks to see if there > are old rows so let's say there are. Your code will do: > > > > For (i = 0; i < numOldRows; i++) > > <delete old row> > > > > Then > > > > For (I = 0; I < numNodes; i++) > > { > > <make an object> > > <add to collection> > > } > > > > That means that: 1) you've converted to object twice and 2) you've > scanned your data set three times if there were old nodes to remove. > > > > And, to make matters worse, calling addItem and removeItem on a > collection is expensive as it must send notifications to everybody who > cares that the collection changed so really the last loop is: > > > > for (I = 0; I < numNodes; i++) > > { > > <make an object> > > <add to collection> > > <collection prepares a change notification> > > } > > > > > > And I can't tell from what you sent, but it appears,you might be setting > the dataprovider on the datagrid inside the loop? If you did that, the > last loop is really: > > > > for (I = 0; I < numNodes; i++) > > { > > <make an object> > > <add to collection> > > <collection prepares and sends a change notification> > > <datagrid handles change by checking seleted index and > scrollbars and more > > <datagrid gets a new dataprovider> > > <datagrid processes getting a new dataprovider> > > } > > > > As you can see, that's a lot of loops doing a lot of work. BTW, I'm not > trying to make you look bad here, plenty of others make these kinds of > mistakes so I'm just using your example to hopefully help many more > folks than just you. > > > > So, how can this be done better? > > > > You could just use resultFormat="e4x". It consumes a lot of memory, but > if you only get one or two queries it may not be fatal. It depends on > your target scenarios. Scott has 1000's of rows fetched many times so > it was definitely fatal for him. The e4x can go straight into the > datagrid without transformation and thus avoiding essentially all of > these loops, but property access to XML is slower so there's a trade-off > there. > > > > I would definitely try to avoid cleaning up the old rows. Properly > designed, you should just be able to abandon the old array of rows w/o > leaking memory as nothing should continue to reference them. > > > > If you do convert to object, I would build up an intermediate array of > objects and then assign it as the .source of the array collection. When > you replace the source in an array collection it should properly abandon > the old array of rows. > > > > Finally, I would consider sticking with resultFormat="e4x" and > converting to the right objects once in the result handler. I've got a > side project going now where I'm pretty much going to do that, although > I'm going to play with an on-the-fly XML to object conversion which I > think will be truly optimal as it won't take time to convert xml nodes > that never get displayed in the datagrid. > > > > And, FWIW, I'm still concerned about your combobox renderers. They can > also be slow to create and initialize and personally, I'm not fond of > the visuals of a stack of them. You can use a ComboBox itemEditor to > allow the user to choose only for the cell currently being edited but > have the plain text be easier on the eyes for the other cells. > > > > HTH, > > -Alex > > > > ________________________________ > > From: [email protected] [mailto:[EMAIL PROTECTED] On > Behalf Of j_lentzz > Sent: Saturday, September 29, 2007 5:26 AM > To: [email protected] > Subject: [flexcoders] Re: HTTPService Performance Issue - very slow > > > > Here are some snippets to show how I'm accessing using the resulting > data - Is this a really slow way to do it? (I've removed some of the > error checking to keep it shorter) > > This is how I point to the data when it returns: > > private var servletScreenData:Object; > private var servletAddEditScreen_LPA_rowsAddedData:Object; // Row data > for embedded rows in widget > > private function handleGetScreenDataResult(event:ResultEvent):void { > if (event.result.getResponse.addEditScreen != null) { > servletScreenData = event.result.getResponse.addEditScreen; > if (event.result.getResponse.addEditScreen.LPA_rowsAdded.row !=null) > > servletAddEditScreen_LPA_rowsAddedData = > event.result.getResponse.addEditScreen.LPA_rowsAdded.row; // Row data > for embedded rows in widget > > I then store it to the parent level fields like this: > if (servletScreenData != null) { > if (servletScreenData.title != null) > addEditScreenTitle.text = servletScreenData.title; > if (servletScreenData.appName != null) > appName.dropDownValue= servletScreenData.appName; > and so on.... > > For the datagrid, I apply it like this: > > // clear out existing data in LPA > LPA_rowsAdded.list=null; > if (servletAddEditScreen_LPA_rowsAddedData != null) { > if (servletAddEditScreen_LPA_rowsAddedData.length > 0) { > for (var j1:int=0; j1<servletAddEditScreen_LPA_rowsAddedData.length; > j1++) { > obj = new Object(); > if (servletAddEditScreen_LPA_rowsAddedData[j1] != null) { > if (servletAddEditScreen_LPA_rowsAddedData[j1].rowdefID != null) > obj.rowdefID = servletAddEditScreen_LPA_rowsAddedData[j1].rowdefID; > if (servletAddEditScreen_LPA_rowsAddedData[j1].fieldName != null) > obj.fieldName = servletAddEditScreen_LPA_rowsAddedData[j1].fieldName; > > and so on to completely fill an object containing the datagrid's row > of data: I then use: > > LPA_rowsAdded.addListItem(obj); > > To add the row of data to the datagrids backing arrayCollection. > > The routine does a little processing to see what type of data it is to > set some defaults, but then it just call: > > _listData.addItem(value); > followed by: > dg.dataProvider = _listData; > dg.rowCount = ROWCOUNTOFFSET + _listData.length; > > to add to the arrayCollection. > > These lines of code are in the loop, so I execute them for each row in > the datagrid. > > Am I just doing something horribly inefficient? > > Thanks for any input. > > John > --- In [email protected] <mailto:flexcoders%40yahoogroups.com> > , "Alex Harui" <aharui@> wrote: > > > > If your resultFormat is Object, I'm pretty sure all of the XML has to > be > > parsed into objects before the busy cursor goes away and the result > > handler fires. I would expect noticeably faster response if the > > resultFormat is e4x. > > > > > > > > But as Scott has found out, memory utilization of XML collections is > > much higher than objects in ArrayCollection. I spent a week studying > > the issue and we've made some improvements in Moxie, but it XML will > > always take more memory and fetching properties out of XML is > measurably > > slower than fetching properties out of objects. Thus, you have to > > trade-off how much XML data you're getting, the time to convert it to > > objects and the time you'd spend accessing it if you didn't convert > it. > > > > > > > > I don't know if anyone has created a background task that will convert > > XML to objects, but I've been thinking about doing that one of these > > days. That would allow you to show more than a busy cursor, but will > > delay the total time until you see the data in the views, so there > will > > be another trade-off. Another twist would be a custom collection that > > converts the XML to objects as they are fetched from the collection. > > > > > > > > You should see the busy cursor "freeze" the moment it tries to do the > > xml conversion to object. Then it should go away and there will be > > another pause while the DG builds the renderers. If you've got lots of > > comboboxes, you'll definitely feel it. A quick way to compare it to > > sub-out the comboboxes for the default renderer and see if you can > tell > > the difference. > > > > > > > > I'll put in trace statements and call getTimer() in "enterFrame" > events > > as way to measure where your time is going. The Moxie beta due out > next > > week has some profiling capability that will help you too, but > > optimizing DG performance will have the biggest payoff. > > > > > > > > ________________________________ > > > > From: [email protected] <mailto:flexcoders%40yahoogroups.com> > [mailto:[email protected] <mailto:flexcoders%40yahoogroups.com> > ] On > > Behalf Of j_lentzz > > Sent: Friday, September 28, 2007 6:54 PM > > To: [email protected] <mailto:flexcoders%40yahoogroups.com> > > Subject: [flexcoders] Re: HTTPService Performance Issue - very slow > > > > > > > > Yes, I am using a result handler. The timers I've used have timed > > from when the result handler gets called until the time I finish > > processing all the data and then let the Flex stuff do its thing. > > This time is very small and I can't start timing any sooner than the > > result handler. I'm sure using extended components vs the heavy > > combobox would help, but I'm confused about why the busy cursor is > > staying on so long. Once it goes away, the complete screen draws > > nearly instantly. Is there anything to be done to speed the > > processing of the incoming data until the result handler is called? > > > > Thanks a bunch, > > > > John > > > > --- In [email protected] > <mailto:flexcoders%40yahoogroups.com> > <mailto:flexcoders%40yahoogroups.com> > > , Scott - FastLane <smelby@> wrote: > > > > > > oops... sorry about the prior message. Doh! > > > > > > It has also been my experience that rendering is usually the > > > bottleneck. See this post on my blog > > <http://blog.fastlanesw.com/?p=25 <http://blog.fastlanesw.com/?p=25> > <http://blog.fastlanesw.com/?p=25 <http://blog.fastlanesw.com/?p=25> > > > > > > for an example of the difference a UIComponent based renderer can > make > > > > > over containers. > > > > > > hth > > > Scott > > > > > > Tracy Spratt wrote: > > > > > > > > In my experience, the rendering of the UI is the bottleneck, not > the > > > > > > data transfer. > > > > > > > > > > > > > > > > Use timer and the result handler function to time the actual data > > > > transfer. You ARE using a result handler, and not binding > > directly to > > > > lastResult, right? > > > > > > > > > > > > > > > > Are your item renderers built on containers? If so, you need to > move > > > > > > to extending UIComponent instead. See Alex Harui's blog for a full > > > > > explanation why, and for many examples. > > > > > > > > > > > > > > > > Tracy > > > > > > > > > > > > > > > > > > ---------------------------------------------------------- > > > > > > > > *From:* [email protected] > <mailto:flexcoders%40yahoogroups.com> > > <mailto:flexcoders%40yahoogroups.com> > > [mailto:[email protected] > <mailto:flexcoders%40yahoogroups.com> > <mailto:flexcoders%40yahoogroups.com> > > ] > > > > *On Behalf Of *j_lentzz > > > > *Sent:* Friday, September 28, 2007 2:11 PM > > > > *To:* [email protected] > <mailto:flexcoders%40yahoogroups.com> > > <mailto:flexcoders%40yahoogroups.com> > > > > *Subject:* [flexcoders] HTTPService Performance Issue - very slow > > > > > > > > > > > > > > > > Hi, > > > > > > > > I've got an app getting data from a server to populate a screen > with > > > > 3, text inputs, some radio buttons and a data grid. With some > data, > > > > it is taking almost a minute to save and refresh the scren. The > data > > > > grid seems to be the issue. It contains many comboboxes. I've read > > > > that these are very slow if too many appear in a datagrid. I see > the > > > > last data leave the server and I have timer marks for when I start > > my > > > > processing of the returned data (populating the arraycollection > for > > > > the datagrid - I'm using the default resultFormat of Object) to > when > > > > I'm done and just waiting on the screen to display it. The > > processing > > > > time I'm getting from the timers is very low (1/2 sec or less). > > > > However, I'm seeing the busy cursor staying on the screen for > almost > > > > the complete time I'm waiting. Once the busy cursor leaves, the > > > > screen appears almost instantly with data. The docs say that the > > busy > > > > cursor is displayed until the class completes loading data. So is > > the > > > > bottleneck on the Flex side (the loading of the data from the > > > > HTTPService) that I can't access? Or is my datagrid full of > > > > comboboxes the issue, even though the busy cursor is staying on > the > > > > screen. > > > > > > > > Any guidance would be appreciated. > > > > > > > > Thanks, > > > > > > > > John > > > > > > > > > > > > > >

