Monday, March 17, 2014

Designing and developing Stock Ticker application in Flex (Part Three)

As we mentioned in part twowe 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.
public class NonBindableStock
{
 public var ticker:String;
 public var company:String;
 [Bindable] public var price:Number;  
 public function NonBindableStock(comp:String, tick:String, prc:Number)
 {
  this.price = prc;
  this.ticker = tick;
  this.company = comp;
 }
}
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:
public class NonBindableStock
{
 public var ticker:String;
 public var company:String;
 public var price:Number;  
 public function NonBindableStock(comp:String, tick:String, prc:Number)
 {
  this.price = prc;
  this.ticker = tick;
  this.company = comp;
 }
}
Now when we change the price we also notify the view by calling itemUpdated() method. So we rewrite the method findAndUpdateNonBindableStock as:
private function findAndUpdateNonBindableStock(ticker:String, updatedPrice:Number):void
{
   var nonBindableStock:NonBindableStock = nonBindableStocksDictionary[ticker] as                                                                    NonBindableStock;
   nonBindableStock.price = updatedPrice;
   nonBindableStocks.itemUpdated(nonBindableStock);
}
This will now update the view as well and we have removed the overhead of binding as well. I have optimized our stock ticker application and I hope you enjoyed this post. Let me know your feedback.


Designing and developing Stock Ticker application in Flex (Part Two)

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

  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.

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):void

This 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.

Designing and developing Stock Ticker application in Flex (Part One)

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).
[Bindable]
public class BindableStock
{
 public var price:Number;
 public var ticker:String;
 public var company:String;
  
 public function BindableStock(comp:String, tick:String, prc:Number)
 {
  this.price = prc;
  this.ticker = tick;
  this.company = comp;
 }
} 


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.
private var bindableStocksDictionary:Dictionary;
[Bindable]private var bindableStocks:ArrayCollection = new ArrayCollection();
private function initializeBindableStocksList():void
{
      var stock1:BindableStock = new BindableStock("Infosys","INF",10.5);
      var stock2:BindableStock = new BindableStock("Oracle","ORC",12.3);
      var stock3:BindableStock = new BindableStock("Amazon","AMZ",23.4);
      var stock4:BindableStock = new BindableStock("Morgan Staley","MRS",39.7);
      var stock5:BindableStock = new BindableStock("Goldman Sachs","GS",13.8);
  
      bindableStocks.addItem(stock1);
      bindableStocks.addItem(stock2);
      bindableStocks.addItem(stock3);
      bindableStocks.addItem(stock4);
      bindableStocks.addItem(stock5);
    
      bindableStocksDictionary = new Dictionary();
      bindableStocksDictionary[stock1.ticker] = stock1;
      bindableStocksDictionary[stock2.ticker] = stock2;
      bindableStocksDictionary[stock3.ticker] = stock3;
      bindableStocksDictionary[stock4.ticker] = stock4;
      bindableStocksDictionary[stock5.ticker] = stock5;
  
}
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:
private function findAndUpdateBindableStock(ticker:String, updatedPrice:Number):void
{
 (bindableStocksDictionary[ticker] as BindableStock).price = updatedPrice;
}



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:
[Bindable]private var bindableStocks:DictionaryCollection = new DictionaryCollection(null,"ticker");
private function initializeBindableStocksList():void
{
      var stock1:BindableStock = new BindableStock("Infosys","INF",10.5);
      var stock2:BindableStock = new BindableStock("Oracle","ORC",12.3);
      var stock3:BindableStock = new BindableStock("Amazon","AMZ",23.4);
      var stock4:BindableStock = new BindableStock("Morgan Staley","MRS",39.7);
      var stock5:BindableStock = new BindableStock("Goldman Sachs","GS",13.8);
  
      bindableStocks.addItem(stock1);
      bindableStocks.addItem(stock2);
      bindableStocks.addItem(stock3);
      bindableStocks.addItem(stock4);
      bindableStocks.addItem(stock5);
}
private function findAndUpdateBindableStock(ticker:String, updatedPrice:Number):void
{
 bindableStocks.getItemByKey(ticker).price = updatedPrice;
}
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.

This will be continued in next part.

Wednesday, March 12, 2014

Why to avoid binding whenever possible?

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.

Lets consider the following example taken from this presentation:

package valueObject

{

  [Bindable]

  public class Product {

    public var productName:String;

  }

}




This code generates a hell lot of code:

package valueObject
{
  import flash.events.IEventDispatcher;
  public class ProductManualBinding implements IEventDispatcher
{
private var dispatcher:flash.events.EventDispatcher = new flash.events.EventDispatcher(flash.events.IEventDispatcher(this ));
    [Bindable(event="propertyChange")]
public function get productName():String {
return _productName;
}
public function set productName(value:String):void {
        var oldValue:Object = _productName;
if (oldValue !== value) {
_productName = value;
dispatchEvent(mx.events.PropertyChangeEvent.
createUpdateEvent(this, "productName",oldValue,value));
}
    }
public function addEventListener(type:String,listener:Function,
useCapture:Boolean= false, priority:int= 0, weakRef:Boolean=false) :void 
{
      dispatcher.addEventListener(type,listener, useCapture,                 priority, weakRef);
}
public function dispatchEvent(event:flash.events.Event):Boolean
{
return dispatcher.dispatchEvent(event);
    }
public function hasEventListener(type:String):Boolean
{
return dispatcher.hasEventListener(type);
}
public function removeEventListener(type:String,
listener:Function, useCapture:Boolean = false):void 
{
        dispatcher.removeEventListener(type, listener, useCapture);
    }
public function willTrigger(type:String):Boolean
{
return dispatcher.willTrigger(type);
}
  }
}
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.

Also check: How to remove binding on an object?

Tuesday, March 11, 2014

How can we remove binding on Object in Flex?

Binding is one important feature of Flex. There are various ways to achieve it. If we use BindingUtils then we get an instance of ChangeWatcher class.
var watcherSetter:ChangeWatcher = 
                    BindingUtils.bindSetter(updateMyString, myTI, "text");
This class (ChangeWatcher) provides method unwatch() to remove the binding. We can also use ChangeWatcher directly as well.
var canWatch:Boolean = ChangeWatcher.canWatch(myObject, 'myProperty');
ChangeWatcher.watch(myObject, 'myProperty', myPropertyChangedHandler) 
BindingUtils is more like a wrapper over it and internally this class make use of ChangeWatcher only. Consider the bindProperty method:
public static function bindProperty(
                                site:Object, prop:String,
                                host:Object, chain:Object,
                                commitOnly:Boolean = false,
                               useWeakReference:Boolean = false):ChangeWatcher
{
    var w:ChangeWatcher =
       ChangeWatcher.watch(host, chain, null, commitOnly, useWeakReference);
        
    if (w != null)
    {
       var assign:Function = function(event:*):void
       {
          site[prop] = w.getValue();
       };
       w.setHandler(assign);
       assign(null);
    }
    return w;
}
and bindSetter method:
public static function bindSetter(setter:Function, host:Object,
                               chain:Object,
                               commitOnly:Boolean = false,
                              useWeakReference:Boolean = false):ChangeWatcher
{
    var w:ChangeWatcher =
       ChangeWatcher.watch(host, chain, null, commitOnly, useWeakReference);
        
    if (w != null)
    {
       var invoke:Function = function(event:*):void
       {
         setter(w.getValue());
       };
       w.setHandler(invoke);
       invoke(null);
    }
    return w;
}
Now the question asked now a days is how can we remove binding on an object? Before answering that lets try to understand what happens in Binding class:
public function Binding(document:Object, srcFunc:Function,
  			        destFunc:Function, destString:String,
				srcString:String = null)
    {
		super();

        this.document = document;
        this.srcFunc = srcFunc;
        this.destFunc = destFunc;
        this.destString = destString;
        this.srcString = srcString;

        if (this.srcFunc == null)
        {
            this.srcFunc = defaultSrcFunc;
        }

        if (this.destFunc == null)
        {
            this.destFunc = defaultDestFunc;
        }

        _isEnabled = true;
        isExecuting = false;
        isHandlingEvent = false;
        hasHadValue = false;
        uiComponentWatcher = -1;

        BindingManager.addBinding(document, destString, this);
    }   
In the constructor it sets various values and then makes call to addBinding() method in BindingManager class.
 public static function addBinding(document:Object, destStr:String,							  b:Binding):void
{
   if (!document._bindingsByDestination)
   {
      document._bindingsByDestination = {};
      document._bindingsBeginWithWord = {};
   }
   document._bindingsByDestination[destStr] = b;
   document._bindingsBeginWithWord[getFirstWord(destStr)] = true;
}

Actually all the bindings are stored in the following arrays:
  • mx_internal _bindings:Array
  • mx_internal _watchers:Array
  • mx_internal _bindingsByDefinitions
  • mx_internal _bindingsBeginWithWord
To remove binding we can use the following method as explained here:
public function removeBindings(object:Object):void
{
   if(!object) return
   if(object._bindings)
   {  
      for(var i:int = 0; i lt object._bindings.length; i++)
        object.bindings[i]= null;
      object._bindings.length = 0;
      object._bindings = null;
   }
   if(object._watchers)
   {
       for(i=0; i lt object._watchers.length; i++)
         object._watchers[i]= null;
       object._watchers.length = 0;
       object._watchers = null;
   }
   if(object._bindingsByDestination)
     object._bindingsByDestination = null;
   if(object._bindingsBeginWithWord
     object._bindingsBeginWithWord = null;
} 
I have used lt for less-than operator as it was getting formatting issues.

That is all and I hope you have enjoyed this post.

How Dictionary Works in Flex

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.
package  {
    import flash.display.Sprite;
    import flash.text.TextField;
    import flash.utils.*;
    public class Benchmark extends Sprite {

        public function Benchmark() {
            var txt:TextField = new TextField();
            this.addChild(txt);
            txt.text = "waiting ...";
            txt.width = 600;        
            const repeat:int = 20;
            const count:int = 100000;
            var d:Dictionary = new Dictionary();
            var j:int, i:int;
            var keys:Array = [];
            for (j = 0; j < repeat * count; j++) {
                keys[j] = { k:j };
            }
            setTimeout(function ():void {
                var idx:int = 0;
                var out:Array = [];
                for (j = 0; j < repeat; j++) {
                    var start:int = getTimer();
                    for (i = 0; i < count; i++) {
                        d[keys[idx++]] = i;
                    }
                    out.push(getTimer() - start);
                }
                txt.appendText("\n" + out);
                start = getTimer();
                for (var k:int = 0; k < i; k++) {
                    test();
                }
                txt.appendText("\ncall:"+(getTimer() - start));
                idx = 0;
                out = [];
                for (j = 0; j < repeat; j++) {
                    start = getTimer();
                    i = 0;
                    for (i = 0; i < count; i++) {
                        delete d[keys[idx++]];
                    }               
                    out.push(getTimer() - start);
                }
                txt.appendText("\n" + out);
            },3000);//wait for player to warm up a little
        }
        private function test():void {}
    }
}

Also HashMaps in java makes use of hashCode() method whereas Dictionary makes use of strict equality (= = = ) of keys and so using object as keys can be a problem in it.

A related aspect is we can also use object to have similar functionality:
var obj:Object = new Object();
obj.something = "something";

var dict:Dictionary = new Dictionary();
dict.something = "something";

trace(obj.something, dict.something);
Then what is the difference? Actually if we are planning to use String keys there is no need for Dictionary class. Though I personally feel that the time of O(1) can still be questionable.

One more point to observe as explained here is:
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".
We cannot make a Dicitonary Bindable. We can find some workaround though: wrapping it in ObjectProxy etc.

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];

But if we reverse the order it will work properly. More here.