Showing posts with label architecture. Show all posts
Showing posts with label architecture. Show all posts

Thursday, May 9, 2013

My first windows phone 8 app - SG News Cloud services

I had a small window of time while waiting for my new job and managed to squeeze an application for windows phone 8. I would like to share my experience and decisions along the way.

Why are you creating applications for windows phone 8 when the smartphone OS is low?
 Well, i am not an expert in iOS/android development, although i have led a full team in delivering mobile solutions, but i didn't had opportunity to write full native applications. With less than 1 week of time, i've decided to leverage on my .NET experience to write an application

What advice do you have for me to be an indie developer hoping to get some passive income?
First of all, if you are an indie developer, plan out your budget & time. Even if you have the best application idea, but if it would requires $500,000 of upfront investment (which you find out in the midst of developing), then you are just wasting your own time. Software licenses, equipment, etc were all consider before i started.

When i decided to make a windows phone app, i've read up on what are the software prerequisites. So for windows phone 8, obviously you would need the Windows Phone 8 SDK, and here are the requirements as well as the link. I would also need a cheap windows phone 8 device (i bought a Lumia 620 for SG$350), as well as the developer account (SG$135).

Can you just tell me how much you spent in total before getting everything up?
SG$135 + SG$350 = SG$485

But that's not all, put into consideration the Windows 8 OS that you need in order to use the SDK. Luckily i gotten my windows 8 key from MSDN subscription.

So you mean i have to subscribe for MSDN in order to get everything running? You know how much it costs?

Frankly, i don't know how much it costs, but i managed to get an MSDN account from BizSpark, a short overview, it's a Microsoft initiative to help 'start-ups'. They provide free Azure & MSDN accounts to kick start your 'business'.

Enough of Q&A, if you have more, do comment on this post. Let me give a short breakdown of the architecture.

Even though i was given a free azure account, after some evaluation, i went ahead with Google App Engine (GAE). Reasons?

  1. Azure was too much fluff and complicated for me to get a simple thing done. Here's a quick wiki look up of what they are offering.
  2. .NET framework is powerful, but too bloated in my case, which might incur high utility costs.

So after deciding on GAE, i was at crossroads once again, Python, Java or Go? I've avoid Azure due to bloat, so no Java. Go is young for my liking, so i went with Python. 

Was it a challenge? 

To my surprise, No. I have zero knowledge on Python but it only took 2 days for everything to start working. Google did a great job in providing python toolkit which offers very useful features, e.g. authentication, authorization, api to Memcached, NoSQL, and many more.

So i hacked up a REST webservice and simple Content Management System (CMS) using GAE, webapp2 and JINJA templates. Tested everything a few rounds and didn't had to bother much about the cloud server anymore. Oh and not to mention GAE gives 1gb of bandwidth daily as opposed to Azure's complicated free tier

I will update with the windows phone 8 application development in my next post :) in the meantime, if you have a windows phone, do take a look SG News

Tuesday, April 6, 2010

Business objects VS Typed Datasets

 I always had this feeling that POCO (Plain old C# objects) will outperform typed datasets & datasets. The main reason why people are using it is only because it lessen development time by a very....... small amount in my opinion. Using business objects are easier to understand and in C# context, the compiler actually do a lot of work for you.

Example in other languages:

public myClass()
{
     private String someString;
  
     public String getString()
    {
        return this.someString;
    }
    public void setString(String value)
    {
        this.someString = value;
    }
}

you can do this in C#:
public myClass()
{
    public String someString { get; set; }
}

That only explains how much it takes to write a Business Object class. Next we go to real work.

I created a simple demo project in VS 2010 (beta), you can use any visual studio to compile this if you want to try it out yourself.

in my Business object class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DemoBizObject
{
    public class BizObject
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Desc { get; set; }
        public decimal price { get; set; }
        public DateTime CreatedDt { get; set; }
        public DateTime ModifiedDt { get; set; }
    }
}

in my aspx code behind, i did this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections.ObjectModel;

using DemoBizObject;
using System.Diagnostics;
using System.Web.UI.DataVisualization.Charting;

namespace DemoWebApp
{
    public partial class _Default : System.Web.UI.Page
    {
        Collection<BizObject> BizObjects = new Collection<BizObject>();
        double[] pocotimings = new double[7];
        double[] typeddstimings = new double[7];

        decimal d = 0.00m;
        const int ONE = 1;
        const int TEN = 10;
        const int ONEHUNDRED = 100;
        const int ONETHOUSAND = 1000;
        const int TENTHOUSAND = 10000;
        const int ONEHUNDREDTHOUSAND = 100000;
        const int ONEMILLION = 1000000;
        const string LINEBREAK = "<br />";

        protected void Page_Load(object sender, EventArgs e)
        {
           
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            this.Label1.Text += "Typed Datasets" + LINEBREAK + LINEBREAK;
            this.Label1.Text += ONE +": "+ demoTypedDS(ONE)+ LINEBREAK;
            this.Label1.Text += TEN + ": " + demoTypedDS(TEN) + LINEBREAK;
            this.Label1.Text += ONEHUNDRED + ": " + demoTypedDS(ONEHUNDRED) + LINEBREAK;
            this.Label1.Text += ONETHOUSAND + ": " + demoTypedDS(ONETHOUSAND) + LINEBREAK;
            this.Label1.Text += TENTHOUSAND + ": " + demoTypedDS(TENTHOUSAND) + LINEBREAK;
            this.Label1.Text += ONEHUNDREDTHOUSAND + ": " + demoTypedDS(ONEHUNDREDTHOUSAND) + LINEBREAK;
            this.Label1.Text += ONEMILLION + ": " + demoTypedDS(ONEMILLION) + LINEBREAK + LINEBREAK;

            this.Label1.Text += "POCO" + ": " + LINEBREAK + LINEBREAK;
            this.Label1.Text += ONE + ": " + demoPOCO(ONE) + LINEBREAK;
            this.Label1.Text += TEN + ": " + demoPOCO(TEN) + LINEBREAK;
            this.Label1.Text += ONEHUNDRED + ": " + demoPOCO(ONEHUNDRED) + LINEBREAK;
            this.Label1.Text += ONETHOUSAND + ": " + demoPOCO(ONETHOUSAND) + LINEBREAK;
            this.Label1.Text += TENTHOUSAND + ": " + demoPOCO(TENTHOUSAND) + LINEBREAK;
            this.Label1.Text += ONEHUNDREDTHOUSAND + ": " + demoPOCO(ONEHUNDREDTHOUSAND) + LINEBREAK;
            this.Label1.Text += ONEMILLION + ": " + demoPOCO(ONEMILLION) + LINEBREAK + LINEBREAK;
        }
        private string demoTypedDS(int numOfRecords)
        {
            typedDS ds = new typedDS();
            Stopwatch watch = Stopwatch.StartNew();
           
            for (int i = 0; i < numOfRecords; i++)
            {
                ds.DemoTable.AddDemoTableRow(i, "demo name", "demo desc", d + i, DateTime.Now, DateTime.Now);
            }
            watch.Stop();
            return watch.Elapsed.TotalSeconds.ToString();
        }
        private string demoPOCO(int numOfRecords)
        {
            BizObject tempObject;
            Stopwatch watch = Stopwatch.StartNew();

            for (int i = 0; i < numOfRecords; i++)
            {
                tempObject = new BizObject();
                tempObject.Id = i;
                tempObject.Name = "demo name";
                tempObject.price = d + i;
                tempObject.CreatedDt = DateTime.Now;
                tempObject.ModifiedDt = DateTime.Now;
                tempObject.Desc = "demo desc";
                BizObjects.Add(tempObject);
            }
            watch.Stop();
            return watch.Elapsed.TotalSeconds.ToString();
        }
    }
}

pardon my messy codes, i didn't want to create this project initially, but i want to be someone that talks the talk and walk the walk.Next, create a similar table in your database with following...


 After that, right click on your solution file and click "Add new item" and select a dataset object.
Double click on the XSD file and go to your DB and drag-and-drop the table onto the XSD and you will get the table there..

The codes are very self explanatory and simple, not much re-using of codes especially @ the printing part.

I ran the test and get the results for POCO VS DS

Results are:
Typed Datasets

1: 4.1E-05
10: 5.47E-05
100: 0.0004515
1000: 0.0045912
10000: 0.0747852
100000: 0.6806366
1000000: 7.4931112

POCO:

1: 5.8E-06
10: 9.6E-06
100: 8.26E-05
1000: 0.0008128
10000: 0.0081756
100000: 0.1015654
1000000: 1.1922586


I tested it several times and dare to confirm that with this demo project, POCO is that Datasets in the lower range (1 to thousands) and the ratio justs exponential when the records reaches millions.

In this test, i only did instantiation and assignment, the Big O notation for:
  • POCO = n Log n 
  • Dataset = C^n
I don't find the need to extract data from database tables and going through the whole cycle as it will end up the same for both, the main difference only occurs when i instantiate and assign values to them. Even with just 6 primitive type objects, typed datasets are giving C^n in terms of performance. That is why my organization's Entity Objects are such a pain in the neck (they used typed datasets plus overriding several events)

Sunday, April 4, 2010

Performance bottleneck? review boxing & unboxing frequencies

There are times where our applications exceed users' response time threshold of 7s (usually), where all action must be completed under 7s.

Page-by-page code reviews are the last resort, but when you are resorting to that, look out of redundant boxing and unboxing of objects, check out: Technet

That's usually my case, or un-necessary objects declaration and recursion.

It's always better to go with iteration than recursion in terms of performance, as well as a typical For loop will outperform a foreach loop due to the boxing and unboxing overhead.

Check the traffic, CPU & memory utilization for resource bottleneck.

The last option is to review the entire architecture of the application (a PM's nightmare as that means a lot of time and resource needs to be pumped into the project). If good architectural designs was laid in place before development start, it wouldn't have to come to this point :)

Wednesday, March 31, 2010

MVC architecture in Sharepoint environment

A lot of webpart developers (from what i observed in MSDN forums) always create webparts with the typical

CreateChildControls() and Render() to generate UI, and attempt to use Render, delegates to control the UI

It's very difficult to understand and code as many people know, but it's actually possible to split all this into 3 well-defined layers.

1st you need : SPMetal to create Entity objects, next you can use Linq to Sharepoint, (Sadly, it's out of support or development by the author as Sharepoint 2010 already have EF v4.0 (Entity Framework), which interop nicely between sharepoint and linq.

2nd you will need your own DAL(Data access layer), with Entity objects already catered for, you should have no problem doing the CRUD with it

3rd: you can use features like QuickPart to render UserControls, have a general idea now? With quickpart, you can generate UI easier, as well as validation, multi-views etc, the list just goes on and on.


And there you go, you have QuickPart as (View), DAL (Controller), SPMetal (Entity objects/Model), however, it still requires more effort to do transactional executions, Singleton/doubleton/n-ton SPWeb, SPSite objects (something like a connection pool).