Monday, March 17, 2014

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.

6 comments:

John Smith said...

Wow!! What a post!!

Tate said...

Great job Akhil!!

This post talks about some serious optimization stuff

NAVEEN said...

Thanks for sharing.Please share the code as attachment.

Naveen

Akhil Mittal said...

Tate,

Welcome.

Akhil Mittal said...

John,

Thanks.

Akhil Mittal said...

Naveen,

The motive of the post is to highlight the code that can be optimized. The relevant code is already posted.

Regards,
Akhil