Monday, March 17, 2014

As we mentioned in part two, we need to optimize the code so as to remove Bindable meta data tag. The bindable code generates lot of bloat code. We can optimize this by removing the Bindable tag and using BindableUtils or ChangeWatcher.We can bind only price property of the stock value object and can make the stock non-bindable.

We can also make use of bindProperty method of BindingUtils and get hold of ChangeWatcher instance. We can remove the binding by calling unwatch() when we do not need it any more. This is straightforward and I am not giving any example for it.

Another optimization in the above case is to keep all the properties non-bindable and take care of notifying the view (datagrid) when data changes in our hand. In this case class will be same as:

As we mentioned in Part One there are two aspects yet to be optimized:

Removing the Bindable tag as it is an overhead and a performance killer and control it ourselves.

Controlling the data grid redraw as every price change is redrawing the whole grid.

Now as we know when we change the price of a stock it leads to collection change event and it leads to full redraw of the grid. There is one idea here where we can prevent the collection change event of update kind and will make the item renderer responsible for the update part. In this case the datagrid will not be redrawn every time and will be a performance booster.Another option I can think of is invalidateCell() method in the spark datagrid. public function invalidateCell(rowIndex:int, columnIndex:int):voidThis method is handy when the specified cell is visible. If the specified cell is visible, it is redisplayed. If variableRowHeight=true, then doing so may cause the height of the corresponding row to change.

If columnIndex is -1, then the entire row is invalidated. Similarly if rowIndex is -1, then the entire column is invalidated.

This method should be called when there is a change to any aspect of the data provider item at rowIndex that might have some impact on the way the specified cell is displayed. Calling this method is similar to calling the dataProvider.itemUpdated() method, which advises the Grid that all rows displaying the specified item should be redisplayed. Using this method can be relatively efficient, since it narrows the scope of the change to a single cell.

This optimizes the redraw of the datagrid as well. Now we need to optimize the code so as to remove Bindable meta data tag. Part 3.

This post talks about many important points regarding the design and development of a stock ticker application in flex. The application is supposed to display the stocks in a datagrid or equivalent component. The price of the stocks will change and it will be changed immediately in datagrid. Let us first consider the performance aspects/assumptions:

1. There will be change in only one property of the stock and it will change very frequently.
2. For updating the price of a stock it needs to be searched among the list of stocks. The property ticker can come handy in identifying the stock out of the list.
3. We need one very effective way to search a stock quickly among a huge list of stocks.
4. We need to control the datagrid refresh and also control the binding events.

Before we go any further let us consider the aspect of locating a stock among the list of stocks. There can be thousands of stocks and looping over all of them to identify one of them can be a performance hit as it would take O(N) time and if these updates will be very frequent it is a serious problem. We can get O(1) time in a Dictionary which is equivalent to HashMap in Java. For time being assume that our stock value object is bindable (all properties as of now, we will improve is later).

Also assume that all the stocks are stored in an array collection in flex. Now change in price (or any other property) will lead to CollectionChangeEvent of update kind. This will further have a bunch of PropertyChangeEvent and the whole datagrid will be redrawn. We will optimize this redraw aspect later.

For optimizing the search we can store all these bindable stocks in dictionary as well. The key can be ticker property and value can be the whole stock object. Now when update comes we will locate them from dictionary and update the price of that stock.

We can bind the arraycollection bindableStocks to data provider of the datagrid or we can make it non-bindable and assign it at run time, but we need to track all the updates in that case. Now the find and update part will look like:

Here we get the stock and update its price and it will be also be reflected in the datagrid. Here we need to track a Dictionary and an ArrayCollection. What about keeping one data structure that will server both the purpose. Here is the idea of DictionaryCollection and the code will be modified as:

Now this looks clean and will be really optimum solution for searching and updating the stock. If we remove the Bindable tag over the stock value object the binding will not be triggered and nothing will work. There are two major things which are still pending:
1. Removing the Bindable tag as it is an overhead and a performance killer and control it ourselves.
2. Controlling the data grid redraw as every price change is redrawing the whole grid.

Wednesday, March 12, 2014

Binding is one nice cool feature and it is used a lot and i really mean a lot!! We see that we get a collection (which is marked bindable mostly) of value objects where every value object is marked with RemoteAlias tag and Bindable tag. We change any of the property and it reflects. Isn't it cool? Yes it is but it comes with a serious performance issue.

Generally experienced programmers (Read it as experts) recommend to avoid binding as much as possible, if not entirely. This feature is overused, frankly. If we know that only 2 properties of the value object will change then making the whole value object bindable is overkill. When we mark the class with Bindable tag at top all its public properties become bindable which may not be needed all the time. It is better tom assign this tag to those properties that may change.

First of all avoid using Bindable it has serious performance problems if used a lot. It generates a lot of code which can have impact on performance. We can keep the value-objects in collection and can handle the job of updating the view manually. We can make use of itemUpdated() method to notify the view whenever the items change in collection. To keep track of changes in collection we can write a handler for collection change event. We should also avoid calling refresh() on array-collection until and unless we really need as this also is a performance problem.

First thing it generates a lot of code. Second thing we can observe is to specify the name of the event in Bindable tag is a good practice. That also has performance impact. The various scenarios are considered here.

If we really need binding then better option is to set binding using BindinhUtils class and get hold of change watcher. When we feel we don't need binding anymore we should remove it immediately by calling unwatch() method using the change watcher instance.

If we think carefully we will observe that most of the times we can skip binding. There are some common misuses of bindings explained in the link.

All of us have used Dictionary in Flex. This is supposed to be HashMap alternative in Flex. As per the documentation:"You can use the Dictionary class to create an associative array that uses objects for keys rather than strings. Such arrays are sometimes called dictionaries, hashes, or maps."

We cannot say that it is implemented exactly in way the HashMap is implemented in Java. Actually we don't know as we cannot check its source code. But we can say one thing that it is very well implemented and it takes O(1) for all operations and it is reasonably fast. We can use the following benchmark taken from Stack Overflow page.

The dictionary[key] does NOT necessarily return the same value as dictionary["key"], even if key.toString() equals "key". However, object[key] will return the same value as object["key"], if key.toString() equals "key".

Another aspect while using Dictionary to store objects is Memory Management. As mentioned in doc:
"As long as any reference to the object exists, the garbage collection system will not recover the memory that the object occupies. If the value of myObject is changed such that it points to a different object or is set to the value null, the memory occupied by the original object becomes eligible for garbage collection, but only if there are no other references to the original object."

So if we set object to null first and then delete from dictionary it will not work. When we set the object to null it does not clear the reference to this in Dictionary so we will not get what we need.valueObject = null;delete myMap[valueObject];