Let me understand the real difference between "tire" and "layer" terms commonly used in architecture.
tire - referes to physical entity that is PC(s) and Server(s) e.g - client machine running webbrowser, app serve running the web app, database server hosting the database.
layer - refers to logical entity that is a component e.g. userinterface layer, business logic layer, data access layer, database layer etc.
The conventiona asp or servlets, jsp or any web app that returns the html content and on the other side queries the database with SQL queries may not be a pure layered architecture because of the overlap of the layer reponsibilities.
A clean layered architecture could be
client - html, javascript, css client talking with a webservice using HTTP GET or POST, all presentation logic is part of javascript and css
dataaccess - webservice interfaceing with database using stored procedure (not SQL queries) to access data and return the data to the client in JSON or XML formats.
database - servers the webservice for the requested data using the stored procedures
The client machines can be many, the webservice if stateless can be
hosted in many servers for scalability reasons, the database server could be hosted in redudant high end server machines for availability reasons.
There are three logical "layers" and 3-tires but actually involving "n" number of physical machines.
client-HTTP(GET/POST)->webservice-TCP database connection ( to execute Stored Proc) ->DB client<-http database="database" font="font" recordset-db="recordset-db" webservice="webservice">-http> No HTML is exchanged between client and webservice. No SQL command is issued by webservice to DB.
The above is a clean layered and tired architecture if the client, webservice and DB are deployed in different machines.
I am trying to understand how this software auto update might be working.
There could be three steps in it
1) Check for the availability of new version
2) Download the latest version
3) Install the downloaded version of software
Next i am going to expand on how each step could be designed or implemented
Check for availability of new version
When the current version of the application is started it could do the following in a background thread
1) Read the current version all the component that could be updated in the software
2) Go the vendor
software update web server and check for the availability of newer version
2.1) Only if the exiting software license supports free updates
3) If newers version ar available the goto step2 or do nothing
Download the latest version
Options
1) Update the software user about the availability of newer version by displaying a message box and request the user for a manual update
2) Update the software user about the availability of newer version by dispaying a message box and request the user to intiate the auto download
2.1) Perform the download in the background (HTTP or FTP)
If download is successfully completed then goto to step 3 or display the error message to the user and the user to try again later.
Install the downloaded version of software
Note: Technology should support installation of newer version when current version of the software is running.
Install the downloaded software and request the user to restart the software.
Not sure how much of the above understanding and ideas are correct?
Magic square! is supported only on, Firefox 3 and above, Safari 3 and above, Google Chrome 3 and above and Internet Explorer 7 and above, web browsers.
Load balance your website.
1) Use DNS (Domain Name Server) to distribute your website load.
2) Use Load Balancing Switch to distribute your website load.
The above mentioned load balancing methods work very well for static websites. But if your website have to do back end processing with a database or any other service, then even those services have to be load balanced otherwise they would become the bottle neck.
The above stuff is just the beginning of the vast topic called "Scalability"!
Abstraction interface
1) System abstraction interface help in hiding the complexity of the actual system and also the changes with in the system transparent to users of the system like hardware upgrade or adding hardware resource to scale up....
Scalability on the client
1) Paging concept (showing only few mail subjects on a mail client)
Scalability on the web/app server
1) multiple threads to handle http request
2) Load balancing architecture (one load balancing proxy server with multiple app server) to handle http request
onConfigurationChanged - orientation change
Having "android:configChanges="orientation|keyboard" in manifest reloads the android activity on orientation change.
Instead the correct property is
addJavascriptInterface - webview & javascript
When passing argument from javascript to android, pass it as string. Now if you want to convert the passed string to Integer or Long, the do not use Integer.getInteger instead use Integer.valueOf, that is, use valueOf. Java Math.ceil with Integers
If your try to do some thing like
Integer a=1;
Integer b=5;
Integer c=0;
c=(int)Math.ceil(a/b);
You will get only 0;
Instead do something like
Integer a=1;
Integer b=5;
Integer c=0;
c=(int)Math.ceil((a * 1.0)/b);
So that you will get 1.
cursor.close() - Right place to close the sqlite cursor
Don't
Try the below script and click on fun2 button. Button inside label tag have some problem, that is the second button invokes the onclick of the first button and then the second button.
Now remove the label (begin and end) tag and try the same code. Everything would work fine.
Let us see some of the most simple javascript scripts optimizations which can make big difference,
Rule: Consider using local variable instead of global variable.
Rule: Avoid using eval() or function constructor.
Rule: Pass function, not string to setTimeout() and setInterval(). Passing stirng is same as calling eval().
Rule: Avoid using with().
For-in loop vs for loop
Slow:
function forinloop()
{
var count=10000;
var arr=new Array();
for(var i=0;i<count;i++)
{
arr[i]=i;
}
var value=0;
for(var index in arr)
{
value+=arr[index];
}
}
Faster:
function forloop()
{
var count=10000;
var arr=new Array();
for(var i=0;i<count;i++)
{
arr[i]=i;
}
var value=0;
count= arr.length;
for(var index=0;index<count;index++)
{
value+=arr[index];
}
}
Rule: Avoid using for-in loop, instead use for() loop.
String concatenation vs array join
Slow:
function stringcat()
{
var count=10000;
var str="";
for(var i=0;i<count;i++)
{
str+="first,";
}
}
Faster:
function arrayjoin()
{
var count=10000;
var arr=new Array();
for(var i=0;i<count;i++)
{
arr[i]="first";
}
var str=arr.join("");
}
Rule: Avoid string concatenation and use array join. The performance difference in significant only in IE 7.
Inbuilt functions vs primitive operations
Slow:
function mathmin()
{
var count=10000;
for(var i=0;i<count;i++)
{
var a=10;
var b=5;
var min = Math.min(a, b);
}
}
Faster:
function primitiveop()
{
var count=10000;
for(var i=0;i<count;i++)
{
var a=10;
var b=5;
var min = a < b ? a : b;
}
}
Rule: Avoid function calls, try to use primitive operations. The performance difference in significant only in IE 7.
External function vs inline function
Slow:
function minfunction(a,b)
{
var min = a < b ? a : b;
return min;
}
function externalfunction()
{
var count=10000;
for(var i=0;i<count;i++)
{
var a=10;
var b=5;
var min=minfunction(a,b);
}
}
Faster:
function inlinefunction()
{
var count=10000;
for(var i=0;i<count;i++)
{
var a=10;
var b=5;
var min = a < b ? a : b;
}
}
Rule: Avoid external function calls, try to use inline functions. The performance difference in significant only in IE 7.
Comments in the script
Slow:
function withcomments()
{
var count=50000;
for(var i=0;i<count;i++)
{
/* dummy comments */
/* dummy comments */
var a=10;
/* dummy comments */
/* dummy comments */
var b=5;
/* dummy comments */
/* dummy comments */
var min = a < b ? a : b;
/* dummy comments */
}
}
Faster:
function withoutcomments()
{
var count=50000;
for(var i=0;i<count;i++)
{
var a=10;
var b=5;
var min = a < b ? a : b;
}
}
Rule: Avoid comments in performance critical script. The performance difference in significant only in IE 7.
Try catch in performance critical functions
Slow:
function withtrycatch()
{
var count=50000;
for(var i=0;i<count;i++)
{
try
{
var num=parseInt("10");
}
catch(e)
{
//handle exception
}
finally
{
}
}
}
Faster:
function withouttrycatch()
{
var count=50000;
for(var i=0;i<count;i++)
{
var num=parseInt("10");
}
}
Rule: Avoid using try catch inside performance critical function.
Developing a website or web application which can be indexed by search engine is very critical and it is called searching engine optimization of the website or web application.
Before starting the optimization let us look at some of the basic rules to be followed
Rule: Focus on the originality and quality of the content of your website.
Rule: Remember your ultimate consumers are your users, not search engines.
Rule: Original content is ranked high in the search result page.
Rule: Increasing the traffic to your website is more important than the rank of the page in the search result.
Rule: Perform any kind of optimization only to improve the user experience.
Below are some of the critical optimization rules
Rule: Use brief, but descriptive title in "title" (<title>Search engine optimization<title/>) tag. Choose a title that effectively communicates the topic of the page's content.
Rule: Create unique title for each page of the website.
Rule: Google search engine does not use keywords "meta" tag (<meta name="keywords" content="search engine optimization, indexing, optimization, rules" />) for indexing.
Rule: Provide crisp and clear description of the webpage in the description "meta" tag (<meta name="description" content="Critical rules for search engine optimization." />). Also provide unique description for each page of the website.
Rule: Use | (pipe) or - (hyphen) as separator and not _ (underscore) in "title" tag and description "meta" tag.
Rule: Provide URLs with readable text (e.g. http://codingrules.blogspot.com/2010/06/unit-testing.html) or keywords to access a webpage and not auto generated text or numbers (e.g. http://codingrules.blogspot.com/2010/06/20006.html).
Rule: Regularly check for broken links and remove the same.
Rule: Provide naturally flowing hierarchy for navigation and text for navigation. Avoid drop down menu, images or animation for navigation.
Rule: Provide site map for the user.
Rule: Submit your website's site map (xml format) with Google's webmaster tools for search engine to index your website. Generate XML site map for your website from http://www.xml-sitemaps.com/. Also Google's webmaster tools help webmasters better control how Google interacts with their websites and get useful information from Google about their site.
Rule: Provide custom 404 page, which can guide user back to a working page.
Rule: Write easy to read text content. Avoid images for textual content.
Rule: Try to use words and phrases on the webpage which the user would be looking for.
Rule: Use descriptive anchor text for links.
Rule: Format links to make it easy for users to distinguish between regular text and the anchor text of links.
Rule: Links on your page maybe internal—pointing to other pages on your site—or external—leading to content on other sites. In either of these cases provide descriptive anchor text for better user experience. Anchor text is the clickable text that users will see as a result of a link,
and is placed within the anchor tag <a href="..."></a>.
Rule: Do not design you entire webpage (or website) as image. Provide some text on the webpage which can be indexed by search engines.
Rule: Use descriptive name for images and not like "img1.png" or "pic.png".
Rule: Provide "alt" and "title" attribute text in the "img" tag (<img alt="" title="" src="" />).
Rule: Use "heading" tags (h1 to h6) to emphasize important text.
Rule: If the company name or the website name is embedded as image, then make sure the same is made available as text in the webpage (e.g. "title" tag or description "meta" tag etc).
Rule: For webpages with photo gallery, apart from providing image "alt" and "title" text, let the users to provide comments, which will increase the textual content of the webpage. But make sure to moderate the user comments.
Rule: User comments section can improve the textual content of the webpage. Moderate the user comments to avoid spam content.
Rule: Provide "Related links" section of links with in your website to increase the traffic to your website.
Rule: Provide complete address of your company on the website either on one of the webpage or on all the pages.
Rule: Use the company/product/service information, where ever applicable, instead of using we or our.
When using parseInt() in javascript to convert or check "08" (e.g. parseInt("08")), then it would return 0. Instead use parseInt("08",10), i.e base 10 for converting or checking.
Save response.php file under apache\htdocs folder in c:\ if you have one.
If you notice the request.html source code the form tag's method attribute is set to GET.
Now open the request.html file using any of your web browser (e.g. http://localhost/request.html).
After the file opens in your web browser, hit the submit button.
Now you can notice the address bar URL had changed to
The above URL is also called Query String.
And the response would be
GET:get value
POST:
The above result is because we used GET method to QUERY/POST data to the server.
Now change the method attribute (form tag) value to POST in the request.html file and save the file.
Now again open the request.html file using any of your web browser (e.g. http://localhost/request.html).
After the file opens in your web browser, hit the submit button.
Now you can notice the address bar URL had changed to
http://localhost/response.php
And the response would be
GET:
POST:post value
The above result is because we used POST method to POST data to the server.
If you want to use JSON with special characters text to write to MySQL database or read from MySQL database using javascript and PHP, follow the below steps
To save/write JSON with special character text, In Javascript
1) Do encodeURIComponent to the value to be submitted in javascript before POST
In PHP
1) Do stripslashes of the received POST data
2) Do mysql_real_escape_string before insert or update SQL statement
To pass back special character text via JSON from database, In PHP
1) Do json_encode before creating JSON string (Note: Do not include " before and after the encoded json value.)
I have been using two laptops for some time. I used to save URL bookmarks in both the laptops. Recently i started using my Nokia 5800 and an iPad for web browsing. I started storing bookmarks in my iPad as well. I found it very difficult to remember the bookmarks and respective devices.
To solve this problem i found a decent enouhg solutions at google bookmarks.
Now i am managing all my bookmarks at google bookmarks. Now i can access my bookmarks from any where and any device!
Let me quickly tell you how to make a USB computer!
1) get one 8/16 GB USB drive.
2) download ubuntu from ubuntu desktop to your PC/laptop.
3) burn the ubuntu iso onto the USB drive as per the instruction given on ubuntu desktop using the universal USB Installer, but select the persistance option ( step 4 in the univsal USB installer ) of your desired memory size.
4) great! Now you have a ubuntu USB computer.
5) now shut down your PC/laptop with out removing the ubuntu USB driver.
6) start your PC/laptop press F12 and a change the boot sequence to boot OS from mounted ubuntu USB drive.
7) do your work with the ubuntu USB drive.
8) once your are done with your work, shut down your PC/laptop and remove the ubuntu USB driver.
9) now carry your ubuntu USB computer where ever you want and mount it on any PC/laptop and do your work!
Let us see some of the most simple javascript scripts optimizations with respect to DHTML which can make big difference,
Caching the DOM element
DIV1 element
DIV2 element
DIV3 element
Slow:
function nodomcache()
{
var count=1000;
for(var i=0;i<count;i++)
{
var value1=document.getElementById("div1").innerHTML;
var value2=document.getElementById("div2").innerHTML;
var value3=document.getElementById("div3").innerHTML;
}
}
Faster:
function domcache()
{
var count=1000;
var ele1=document.getElementById("div1");
var ele2=document.getElementById("div2");
var ele3=document.getElementById("div3");
for(var i=0;i<count;i++)
{
var value1=ele1.innerHTML;
var value2=ele2.innerHTML;
var value3=ele3.innerHTML;
}
}
Rule: Cache the element for better performance. This caching is applicable for all types or variables.
Creating dynamic HTML (appendChild vs innerHTML)
Slow:
function appendchildhtml()
{
var count=100;
var tblele=document.createElement("table");
var tblbodyele=document.createElement("tbody");
for(var i=0;i<count;i++)
{
var trele= document.createElement("tr");
var tdele1= document.createElement("td");
tdele1.appendChild(document.createTextNode(i))
trele.appendChild(tdele1);
var tdele2= document.createElement("td");
tdele2.appendChild(document.createTextNode(i))
trele.appendChild(tdele2);
tblbodyele.appendChild(trele);
}
tblele.appendChild(tblbodyele);
document.getElementById("result1").appendChild(tblele);
}
Faster:
function innerhtml()
{
var count=100;
var strHTML="";
strHTML+="<table>";
for(var i=0;i<count;i++)
{
strHTML+="<tr>";
strHTML+="<td>";
strHTML+=i;
strHTML+="</td>";
strHTML+="<td>";
strHTML+=i;
strHTML+="</td>";
strHTML+="</tr>";
}
strHTML+="</table>";
document.getElementById("result2").innerHTML=strHTML;
}
Rule: Use innerHTML for dynamically adding html content.
The example first creates and populates an AddressBook class with 10000 Contact objects and measures time taken to generate the xml file with 10000 contacts using using XmlDocument, XmlWriter and StreamWriter (usign StringBuilder).
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.IO;
using System.Diagnostics;
using System.Xml.Linq;
namespace XmlWrite
{
class Contact
{
public string Name { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public int Zip { get; set; }
public string Phone { get; set; }
public Contact(string strName, string strAddress1, string strAddress2,
int iZip,
string strPhone)
{
Name = strName;
Address1 = strAddress1;
Address2 = strAddress2;
Zip = iZip;
Phone = strPhone;
}
}
class AddressBook
{
private List<Contact> InnerList = null;
public List<Contact> GetContacts()
{
return InnerList;
}
public AddressBook()
{
InnerList = new List<Contact>();
}
public void Add(Contact objContact)
{
InnerList.Add(objContact);
}
}
class Program
{
static void Main(string[] args)
{
Stopwatch objSW = null;
XmlDocument objXmlDoc = null;
XmlWriter objXmlWriter = null;
XDocument objXDoc = null;
StringBuilder objSB = null;
StreamWriter objStreamWriter = null;
AddressBook objAddrBook = null;
int iCount = 10000;
List<Contact> objContacts = null;
//populate contacts in the addressbook object model
objAddrBook = new AddressBook();
objSW = new Stopwatch();
for (int i = 0; i < iCount; i++)
{
Contact objContact = null;
string strName = "Person" + (i + 1);
string strAddress1 = "Number" + (i + 101);
string strAddress2 = "Address" + (i + 501);
int iZip = 50000 + (i + 1);
string strPhone = "99999" + (i + 1);
objContact = new Contact(strName, strAddress1, strAddress2, iZip,
strPhone);
objAddrBook.Add(objContact);
}
//xml creation using XmlDocument
objSW.Reset();
objSW.Start();
objXmlDoc = new XmlDocument();
XmlElement objXmlAddrBook = objXmlDoc.CreateElement("AddressBook");
objContacts = objAddrBook.GetContacts();
for (int i = 0; i < objContacts.Count; i++)
{
XmlElement objXmlContact = objXmlDoc.CreateElement("Contact");
XmlElement objXmlName = objXmlDoc.CreateElement("Name");
objXmlName.InnerText = objContacts[i].Name;
objXmlContact.AppendChild(objXmlName);
XmlElement objXmlAddress1 = objXmlDoc.CreateElement("Address1");
objXmlAddress1.AppendChild(
objXmlDoc.CreateCDataSection(objContacts[i].Address1));
objXmlContact.AppendChild(objXmlAddress1);
XmlElement objXmlAddress2 = objXmlDoc.CreateElement("Address2");
objXmlAddress2.AppendChild(
objXmlDoc.CreateCDataSection(objContacts[i].Address2));
objXmlContact.AppendChild(objXmlAddress2);
XmlElement objXmlZip = objXmlDoc.CreateElement("Zip");
objXmlZip.InnerText = objContacts[i].Zip.ToString();
objXmlContact.AppendChild(objXmlZip);
XmlElement objXmlPhone = objXmlDoc.CreateElement("Phone");
objXmlPhone.AppendChild(
objXmlDoc.CreateCDataSection(objContacts[i].Phone));
objXmlContact.AppendChild(objXmlPhone);
objXmlAddrBook.AppendChild(objXmlContact);
}
objXmlDoc.AppendChild(objXmlAddrBook);
objXmlDoc.Save("address_dom.xml");
objSW.Stop();
Console.WriteLine("XML file created using XmlDocument");
Console.WriteLine("TimeElapsed (Stopwatch float):{0}ms",
objSW.Elapsed.TotalMilliseconds);
Console.WriteLine("TimeElapsed (Stopwatch rounded):{0}ms",
objSW.ElapsedMilliseconds);
//xml creation using XmlWriter
objSW.Reset();
objSW.Start();
XmlWriterSettings objSettings = new XmlWriterSettings();
objSettings.Indent = true;
using (objXmlWriter = XmlWriter.Create("address_xw.xml", objSettings))
{
objXmlWriter.WriteStartElement("AddressBook");
objContacts = objAddrBook.GetContacts();
for (int i = 0; i < objContacts.Count; i++)
{
objXmlWriter.WriteStartElement("Contact");
objXmlWriter.WriteStartElement("Name");
objXmlWriter.WriteString(objContacts[i].Name);
objXmlWriter.WriteEndElement();
objXmlWriter.WriteStartElement("Address1");
objXmlWriter.WriteCData(objContacts[i].Address1);
objXmlWriter.WriteEndElement();
objXmlWriter.WriteStartElement("Address2");
objXmlWriter.WriteCData(objContacts[i].Address2);
objXmlWriter.WriteEndElement();
objXmlWriter.WriteStartElement("Zip");
objXmlWriter.WriteString(objContacts[i].Zip.ToString());
objXmlWriter.WriteEndElement();
objXmlWriter.WriteStartElement("Phone");
objXmlWriter.WriteCData(objContacts[i].Phone);
objXmlWriter.WriteEndElement();
objXmlWriter.WriteEndElement();
}
objXmlWriter.WriteEndElement();
}
objSW.Stop();
Console.WriteLine("XML file created using XmlWriter");
Console.WriteLine("TimeElapsed (Stopwatch float):{0}ms",
objSW.Elapsed.TotalMilliseconds);
Console.WriteLine("TimeElapsed (Stopwatch rounded):{0}ms",
objSW.ElapsedMilliseconds);
//xml creation using StringBuilder
objSW.Reset();
objSW.Start();
objSB = new StringBuilder();
objSB.AppendLine("<AddressBook>");
objContacts = objAddrBook.GetContacts();
for (int i = 0; i < objContacts.Count; i++)
{
objSB.AppendLine("<Contact>");
objSB.AppendLine("<Name>" + objContacts[i].Name + "</Name>");
objSB.AppendLine(
"<Address1><![CDATA[" + objContacts[i].Address1 + "]]></Address1>");
objSB.AppendLine(
"<Address2><![CDATA[" + objContacts[i].Address2 + "]]></Address2>");
objSB.AppendLine("<Zip>" + objContacts[i].Zip + "</Zip>");
objSB.AppendLine(
"<Phone><![CDATA[" + objContacts[i].Phone + "]]></Phone>");
objSB.AppendLine("</Contact>");
}
objSB.AppendLine("</AddressBook>");
using (objStreamWriter = new StreamWriter("address_sb.xml", false))
{
objStreamWriter.Write(objSB.ToString());
}
objSW.Stop();
Console.WriteLine("XML file created using StringBuilder");
Console.WriteLine("TimeElapsed (Stopwatch float):{0}ms",
objSW.Elapsed.TotalMilliseconds);
Console.WriteLine("TimeElapsed (Stopwatch rounded):{0}ms",
objSW.ElapsedMilliseconds);
//xml creation using XDocument (LINQ)
objSW.Reset();
objSW.Start();
objContacts = objAddrBook.GetContacts();
XElement[] arrXElem = new XElement[objContacts.Count];
for (int i = 0; i < objContacts.Count; i++)
{
arrXElem[i] = new XElement("Contact",
new XElement("Name", objContacts[i].Name),
new XElement("Address1",
new XCData(objContacts[i].Address1)),
new XElement("Address2",
new XCData(objContacts[i].Address2)),
new XElement("Zip", objContacts[i].Zip),
new XElement("Phone", new XCData(objContacts[i].Phone)));
}
objXDoc = new XDocument(new XElement("AddressBook",arrXElem));
objXDoc.Save("address_xdocument.xml");
objSW.Stop();
Console.WriteLine("XML file created using XDocument");
Console.WriteLine("TimeElapsed (Stopwatch float):{0}ms",
objSW.Elapsed.TotalMilliseconds);
Console.WriteLine("TimeElapsed (Stopwatch rounded):{0}ms",
objSW.ElapsedMilliseconds);
Console.ReadLine();
}
}
}
Output:
XML file created using XmlDocument
TimeElapsed (Stopwatch float):90.0323ms
TimeElapsed (Stopwatch rounded):90ms
XML file created using XmlWriter
TimeElapsed (Stopwatch float):36.2555ms
TimeElapsed (Stopwatch rounded):36ms
XML file created using StringBuilder
TimeElapsed (Stopwatch float):91.5911ms
TimeElapsed (Stopwatch rounded):91ms
XML file created using XDocument
TimeElapsed (Stopwatch float):71.3794ms
TimeElapsed (Stopwatch rounded):71ms
Note: The StringBuilder performance can be improved by specifying the required capacity when creating the StringBuilder object.
Note: XmlDocument can be considered, if forward and backward reference is unavoidable during the generation of xml document.
Rule: Use XmlWriter for generating or creating xml document.
Structure performs better than the reference type (Class) with respect to CPU usage and memory usage. Consider using structure over class,
If your application has to support data which does not require inheritance and interface
The data is in large number
The data is only of primitive data type like integer, byte, float, etc.
Probability a graphics application or application which deals with large data
Note: Structure with large number of members will degrade the performance when passed as parameter/argument to functions because the values of the entire structure is copied as parameter/argument to the function.
Below code measures the creation of 100000 objects of a class and also measures the time taken to search an object from the collection.
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Drawing;
namespace ClassTimeElapsed
{
class Brick
{
public int Id;
public float X;
public float Y;
public float Width;
public float Height;
public Color Color;
}
class Program
{
static void Main(string[] args)
{
Stopwatch objStopwatch;
Brick[] arrBrick;
int iCount;
iCount = 100000;
objStopwatch = new Stopwatch();
objStopwatch.Reset();
objStopwatch.Start();
arrBrick = new Brick[iCount];
for (int i = 0; i < iCount; i++)
{
arrBrick[i] = new Brick();
}
int iConst = 15;
for (int i = 0; i < iCount; i++)
{
arrBrick[i].Id = i + 1;
arrBrick[i].X = i * iConst;
arrBrick[i].Y = 0;
arrBrick[i].Width = 10;
arrBrick[i].Height = 10;
arrBrick[i].Color = Color.Teal;
}
objStopwatch.Stop();
Console.WriteLine(
"Class time elapsed for allocation and population");
//timeelapsed
Console.WriteLine("TimeElapsed (Stopwatch float):{0}ms",
objStopwatch.Elapsed.TotalMilliseconds);
Console.WriteLine("TimeElapsed (Stopwatch rounded):{0}ms",
objStopwatch.ElapsedMilliseconds);
int iSearchId = 99880;
Brick objBrick = null;
objStopwatch.Reset();
objStopwatch.Start();
for (int i = 0; i < arrBrick.Length; i++)
{
if (iSearchId == arrBrick[i].Id)
{
objBrick = arrBrick[i];
break;
}
}
objStopwatch.Stop();
Console.WriteLine(
"Class time elapsed for searching");
//search result
Console.WriteLine(
"search result: Id:{0},X:{1},Y:{2},Width:{3},Height:{4},Color:{5}",
objBrick.Id, objBrick.X, objBrick.Y, objBrick.Width, objBrick.Height,
objBrick.Color);
//timeelapsed
Console.WriteLine("TimeElapsed (Stopwatch float):{0}ms",
objStopwatch.Elapsed.TotalMilliseconds);
Console.WriteLine("TimeElapsed (Stopwatch rounded):{0}ms",
objStopwatch.ElapsedMilliseconds);
Console.ReadLine();
}
}
}
Output:
Class time elapsed for allocation and population
TimeElapsed (Stopwatch float):13.7327ms
TimeElapsed (Stopwatch rounded):13ms
Class time elapsed for searching
search result: Id:99880,X:1498185,Y:0,Width:10,Height:10,Color:Color [Teal]
TimeElapsed (Stopwatch float):1.3015ms
TimeElapsed (Stopwatch rounded):1ms
Below code measures the creation of 100000 objects of a struct and also measures the time taken to search an object from the collection.
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Drawing;
namespace StructTimeElapsed
{
struct Brick
{
public int Id;
public float X;
public float Y;
public float Width;
public float Height;
public Color Color;
}
class Program
{
static void Main(string[] args)
{
Stopwatch objStopwatch;
Brick[] arrBrick;
int iCount;
iCount = 100000;
objStopwatch = new Stopwatch();
objStopwatch.Reset();
objStopwatch.Start();
arrBrick = new Brick[iCount];
int iConst = 15;
for (int i = 0; i < iCount; i++)
{
arrBrick[i].Id = i + 1;
arrBrick[i].X = i * iConst;
arrBrick[i].Y = 0;
arrBrick[i].Width = 10;
arrBrick[i].Height = 10;
arrBrick[i].Color = Color.Teal;
}
objStopwatch.Stop();
Console.WriteLine(
"Struct time elapsed for allocation and population");
//timeelapsed
Console.WriteLine("TimeElapsed (Stopwatch float):{0}ms",
objStopwatch.Elapsed.TotalMilliseconds);
Console.WriteLine("TimeElapsed (Stopwatch rounded):{0}ms",
objStopwatch.ElapsedMilliseconds);
int iSearchId = 99880;
Brick objBrick;
objBrick.Id = 0;
objBrick.X = 0;
objBrick.Y = 0;
objBrick.Width = 0;
objBrick.Height = 0;
objBrick.Color = Color.Transparent;
objStopwatch.Reset();
objStopwatch.Start();
for (int i = 0; i < arrBrick.Length; i++)
{
if (iSearchId == arrBrick[i].Id)
{
objBrick = arrBrick[i];
break;
}
}
objStopwatch.Stop();
Console.WriteLine(
"Struct time elapsed for searching");
//search result
Console.WriteLine(
"search result: Id:{0},X:{1},Y:{2},Width:{3},Height:{4},Color:{5}",
objBrick.Id, objBrick.X, objBrick.Y, objBrick.Width, objBrick.Height,
objBrick.Color);
//timeelapsed
Console.WriteLine("TimeElapsed (Stopwatch float):{0}ms",
objStopwatch.Elapsed.TotalMilliseconds);
Console.WriteLine("TimeElapsed (Stopwatch rounded):{0}ms",
objStopwatch.ElapsedMilliseconds);
Console.ReadLine();
}
}
}
Output:
Struct time elapsed for allocation and population
TimeElapsed (Stopwatch float):3.0684ms
TimeElapsed (Stopwatch rounded):3ms
Struct time elapsed for searching
search result: Id:99880,X:1498185,Y:0,Width:10,Height:10,Color:Color [Teal]
TimeElapsed (Stopwatch float):1.0981ms
TimeElapsed (Stopwatch rounded):1ms
Below code measures the memory usage of creation of 100000 objects of a class.
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Drawing;
namespace ClassMemoryUsage
{
class Brick
{
public int Id;
public float X;
public float Y;
public float Width;
public float Height;
public Color Color;
}
class Program
{
static void Main(string[] args)
{
long lngGCMemStart = 0;
long lngGCMemEnd = 0;
long lngProcessMemStart = 0;
long lngProcessMemEnd = 0;
Brick[] arrBrick;
int iCount;
iCount = 100000;
Process objProcess = Process.GetCurrentProcess();
//Measure starting point memory
lngGCMemStart = System.GC.GetTotalMemory(true);
lngProcessMemStart = objProcess.PrivateMemorySize64;
arrBrick = new Brick[iCount];
for (int i = 0; i < iCount; i++)
{
arrBrick[i] = new Brick();
}
//Measure memory after allocating
lngGCMemEnd = System.GC.GetTotalMemory(true);
lngProcessMemEnd = objProcess.PrivateMemorySize64;
int iConst = 15;
for (int i = 0; i < iCount; i++)
{
arrBrick[i].Id = i+1;
arrBrick[i].X = i*iConst;
arrBrick[i].Y = 0;
arrBrick[i].Width = 10;
arrBrick[i].Height = 10;
arrBrick[i].Color = Color.Teal;
}
Console.WriteLine("Class memory usage.");
//memoryusage difference
Console.WriteLine("GC Memory Use:{0} (bytes)",
lngGCMemEnd - lngGCMemStart);
Console.WriteLine("Process Memory Use:{0} (bytes)",
lngProcessMemEnd - lngProcessMemStart);
Console.WriteLine("GC Memory Start:{0} (bytes)",
lngGCMemStart.ToString());
Console.WriteLine("Process Memory Start:{0} (bytes)",
lngProcessMemStart.ToString());
Console.WriteLine("GC Memory End:{0} (bytes)",
lngGCMemEnd.ToString());
Console.WriteLine("Process Memory End:{0} (bytes)",
lngProcessMemEnd.ToString());
Console.ReadLine();
}
}
}
Output:
Class memory usage.
GC Memory Use:4802368 (bytes)
Process Memory Use:0 (bytes)
GC Memory Start:130648 (bytes)
Process Memory Start:9232384 (bytes)
GC Memory End:4933016 (bytes)
Process Memory End:9232384 (bytes)
Below code measures the memory usage of creation of 100000 objects of a struct.
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Drawing;
namespace StructMemoryUsage
{
struct Brick
{
public int Id;
public float X;
public float Y;
public float Width;
public float Height;
public Color Color;
}
class Program
{
static void Main(string[] args)
{
long lngGCMemStart = 0;
long lngGCMemEnd = 0;
long lngProcessMemStart = 0;
long lngProcessMemEnd = 0;
Brick[] arrBrick;
int iCount;
iCount = 100000;
Process objProcess = Process.GetCurrentProcess();
//Measure starting point memory
lngGCMemStart = System.GC.GetTotalMemory(true);
lngProcessMemStart = objProcess.PrivateMemorySize64;
arrBrick = new Brick[iCount];
//Measure memory after allocating
lngGCMemEnd = System.GC.GetTotalMemory(true);
lngProcessMemEnd = objProcess.PrivateMemorySize64;
int iConst = 15;
for (int i = 0; i < iCount; i++)
{
arrBrick[i].Id = i + 1;
arrBrick[i].X = i * iConst;
arrBrick[i].Y = 0;
arrBrick[i].Width = 10;
arrBrick[i].Height = 10;
arrBrick[i].Color = Color.Teal;
}
Console.WriteLine("Struct memory usage.");
//memoryusage difference
Console.WriteLine("GC Memory Use:{0} (bytes)",
lngGCMemEnd - lngGCMemStart);
Console.WriteLine("Process Memory Use:{0} (bytes)",
lngProcessMemEnd - lngProcessMemStart);
Console.WriteLine("GC Memory Start:{0} (bytes)",
lngGCMemStart.ToString());
Console.WriteLine("Process Memory Start:{0} (bytes)",
lngProcessMemStart.ToString());
Console.WriteLine("GC Memory End:{0} (bytes)",
lngGCMemEnd.ToString());
Console.WriteLine("Process Memory End:{0} (bytes)",
lngProcessMemEnd.ToString());
Console.ReadLine();
}
}
}
Output:
Struct memory usage.
GC Memory Use:3602368 (bytes)
Process Memory Use:0 (bytes)
GC Memory Start:130656 (bytes)
Process Memory Start:9232384 (bytes)
GC Memory End:3733024 (bytes)
Process Memory End:9232384 (bytes)
Why?
Structure is created in the stack.Structure is a value type.
Rule: Consider using structure for supporting large number of objects(data) in your application.
Use StringBuilder for string concatenation. Concatenation of string using StringBuilder has better performance over string.
Below code measures the time taken to concatenate a string for 5000 iteration using “string” and “StringBuilder”.
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
namespace StringVsStringBuilder
{
class Program
{
static void Main(string[] args)
{
Stopwatch objStopwatch = new Stopwatch();
string strValue=string.Empty;
StringBuilder objSBValue = new StringBuilder();
int iCount = 5000;
objStopwatch.Reset();
objStopwatch.Start();
for (int i = 0; i < iCount; i++)
{
strValue = strValue+"simpleValue"+i.ToString();
}
objStopwatch.Stop();
Console.WriteLine("concatenation using String.");
Console.WriteLine(
"TimeElapsed (Stopwatch float):{0}ms",
objStopwatch.Elapsed.TotalMilliseconds
);
Console.WriteLine(
"TimeElapsed (Stopwatch rounded):{0}ms",
objStopwatch.ElapsedMilliseconds
);
//Console.WriteLine(strValue);
objStopwatch.Reset();
objStopwatch.Start();
for (int i = 0; i < iCount; i++)
{
objSBValue.Append("simpleValue" + i.ToString());
}
objStopwatch.Stop();
Console.WriteLine(
"concatenation using StringBuilder."
);
Console.WriteLine(
"TimeElapsed (Stopwatch float):{0}ms",
objStopwatch.Elapsed.TotalMilliseconds
);
Console.WriteLine(
"TimeElapsed (Stopwatch rounded):{0}ms",
objStopwatch.ElapsedMilliseconds
);
//Console.WriteLine(objSBValue);
Console.ReadLine();
}
}
}
Output:
concatenation using String.
TimeElapsed (Stopwatch float):316.6526ms
TimeElapsed (Stopwatch rounded):316ms
concatenation using StringBuilder.
TimeElapsed (Stopwatch float):2.4933ms
TimeElapsed (Stopwatch rounded):2ms
Why?
Any object stored in heap is immutable with respect to size allocation, and any change to the underlying size will require reallocation. If the string is modified (concatenating another string onto it, changing its value), then a new string is created and this can have negative performance implications. The StringBuilder gets around the reallocation problem by using internal buffers. But once the buffer fills up, the reallocation occurs. It is recommended to specify the initial capacity to minimize the reallocation problem.
Rule: Use StringBuilder instead of string for string concatenation operation.
Use Xmlreader for parse xml document.
Create an xml file as show below, but with 10000 contact elements called as “address_xw_n.xml” and make it available in D driver (d:\).
The below code demonstrate the time take to parse the above created xml file using XmlDocument, XDocument and XmlReader.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Diagnostics;
using System.Xml.Linq;
namespace XmlParse
{
class Program
{
static void Main(string[] args)
{
Stopwatch objSW = null;
String strNormalFilePath;
strNormalFilePath = @"d:\address_xw_n.xml";
XmlDocument xmlNDoc;
XmlReader xmlNReader = null;
XDocument xNDoc=null;
objSW = new Stopwatch();
//xml parsing using XmlDocument - Normal format
objSW.Reset();
objSW.Start();
xmlNDoc = new XmlDocument();
xmlNDoc.Load(strNormalFilePath);
XmlElement xmlDocNElem = xmlNDoc.DocumentElement;
for (int i = 0; i < xmlDocNElem.ChildNodes.Count; i++)
{
XmlNode xmlNode = xmlDocNElem.ChildNodes[i];
for (int j = 0; j < xmlNode.ChildNodes.Count; j++)
{
string strName = xmlNode.ChildNodes[j].Name;
string strValue = xmlNode.ChildNodes[j].ChildNodes[0].Value;
//Console.WriteLine(strName + "-" + strValue);
}
}
//xmlNDoc = null;
objSW.Stop();
Console.WriteLine("XML parsing using XmlDocument - Normal format");
Console.WriteLine("TimeElapsed (Stopwatch float):{0}ms",
objSW.Elapsed.TotalMilliseconds);
Console.WriteLine("TimeElapsed (Stopwatch rounded):{0}ms",
objSW.ElapsedMilliseconds);
//xml parsing using XDocument - Normal format
objSW.Reset();
objSW.Start();
xNDoc = XDocument.Parse(xmlNDoc.OuterXml);
foreach (XElement e in xNDoc.Root.Elements())
{
foreach (XElement c in e.Elements())
{
string strName = c.Name.ToString();
string strValue = c.Value;
//Console.WriteLine(strName+"-"+strValue);
}
}
xNDoc = null;
objSW.Stop();
Console.WriteLine("XML parsing using XDocument - Normal format");
Console.WriteLine("TimeElapsed (Stopwatch float):{0}ms",
objSW.Elapsed.TotalMilliseconds);
Console.WriteLine("TimeElapsed (Stopwatch rounded):{0}ms",
objSW.ElapsedMilliseconds);
//xml parsing using XmlReader - Normal format
objSW.Reset();
objSW.Start();
using (xmlNReader = XmlReader.Create(strNormalFilePath))
{
while (xmlNReader.Read())
{
switch (xmlNReader.NodeType)
{
case XmlNodeType.Element:
{
switch (xmlNReader.Name)
{
case "Name":
case "Zip":
{
string strName = xmlNReader.Name;
xmlNReader.Read();
string strValue = xmlNReader.Value;
//Console.WriteLine(strName +
// "-" + strValue);
break;
}
case "Address1":
case "Address2":
case "Phone":
{
string strName = xmlNReader.Name;
xmlNReader.Read();
string strValue = xmlNReader.Value;
//Console.WriteLine(strName +
// "-" + strValue);
break;
}
}
break;
}
}
}
}
objSW.Stop();
Console.WriteLine("XML parsing using XmlReader - Normal format");
Console.WriteLine("TimeElapsed (Stopwatch float):{0}ms",
objSW.Elapsed.TotalMilliseconds);
Console.WriteLine("TimeElapsed (Stopwatch rounded):{0}ms",
objSW.ElapsedMilliseconds);
Console.ReadLine();
}
}
}
Output:
XML parsing using XmlDocument - Normal format
TimeElapsed (Stopwatch float):5232.8249ms
TimeElapsed (Stopwatch rounded):5232ms
XML parsing using XDocument - Normal format
TimeElapsed (Stopwatch float):114.9677ms
TimeElapsed (Stopwatch rounded):114ms
XML parsing using XmlReader - Normal format
TimeElapsed (Stopwatch float):42.7921ms
TimeElapsed (Stopwatch rounded):42ms
Note: XmlDocument can be considered, if forward and backward reference is unavoidable during the parsing of xml document.