I am a little blue fellow

little blue fellow
likes to share

  • open source story
  • startup story
  • coding
JavaScript String match

the unfortunate cat

the unfortunate cat

[C#] how bad is it – String Concatenation

+= is often mentioned bad to use in a loop. But how bad is it?

consider the following code:

            Stopwatch watch1 = new Stopwatch();
            Stopwatch watch2 = new Stopwatch();
            String s1 = "";
            String s2 = "";
            int count = 20000;
            watch1.Start();
            for (int i = 0; i < count; i++)
            {
                s1 += i.ToString();
            }
            watch1.Stop();
            Console.WriteLine(watch1.ElapsedMilliseconds);

            watch2.Start();
            StringBuilder sb = new StringBuilder(s2);
            for (int i = 0; i < count; i++)
            {
                sb.Append(i.ToString());
            }
            s2 = sb.ToString();
            watch2.Stop();
            Console.WriteLine(watch2.ElapsedMilliseconds);

Result:
watch1: 2206
watch2: 7

wow…it seems really bad…

more on String Concatenation in C#

[javascript] How bad is it – Modification DOM Tree

a simple test on modification Dom Tree
timing by time.js

Code:

window.onload = function() {
	time.start('page load');
	var div = document.getElementById("thediv");
	var i=5000; while(i--){
		div.appendChild(document.createElement("a"));
	}
	time.stop('page load');
	
	time.start('page load 2');
	var div2 = document.getElementById("thediv2");
	var fragment = document.createDocumentFragment();
	var i=5000; while(i--){
		fragment.appendChild(document.createElement("a"));
	}
	div2.appendChild(fragment.cloneNode(true));
	time.stop('page load 2');
	
	time.report();
}

Result: Windows 7 Professional
Firefox 3.6.12
page load: 746ms
page load 2: 371ms

Opera 10.63
page load: 19ms
page load 2: 19ms

IE 8.0.7600.16385
page load: 160ms
page load 2: 152ms

IE 6.0
page load: 140ms
page load 2: 150ms

[Visual Studio] Generat MD5 Checksum After Build

Download:

  1. MD5sums for Windows
  2. Unzip it and place it to any folder you want

Configure Post-build event command line:
YOUR_MD5SUMS_PATH “$(TargetPath)”
e.g.

c:\tool\md5sums-1.2\md5sums.exe "$(TargetPath)"

Output

CtpGglMap.dll        f81e28e975317a8499af08a9b740be63

[YUI] Things You Should Know About YUI – Throws Error

YAHOO.util.Event.throwErrors is important and often ignored in YUI. The default value for this is false. As a result, any javascript error will be caught and ignored(but written in YUI debug console) in event callback.

e.g.
consider following code:

var evnt = new YAHOO.util.CustomEvent("myevent",{name:"scope"});
evnt.subscribe(
	function(type, args, me){
		console.log(this);
		console.log(args);
		console.log(me);
	},
	{name:"me"})
evnt.fire({name:"args"});

it works fine and print out values in FireBug console. what happen if we make typo

var evnt = new YAHOO.util.CustomEvent("myevent",{name:"scope"});
evnt.subscribe(
	function(type, args, me){
		console.log(this);
		console.lg(args); //typo
		console.log(me);
	},
	{name:"me"})
evnt.fire({name:"args"});

ops….nothing happens. no error message! if one doesn’t spot the typo at first, going to take long time to debug.

the trick is simple and easy

YAHOO.util.Event.throwErrors = true;

[C#] indexer – very interesting feature

indexer , a very very interesting feature in C# to use object as array.

sampe code – FakeDB.cs
usage:

FakeDB db = FakeDB.GetFakeDB();
DataTable table = new DataTable("project");
/* use table */
db["project"] = table;
 public class FakeDB
    {
        //Global Variable
        private static FakeDB theFakeDB = null;
        //Singleton pattern 
        private FakeDB() {
            Tables = new Dictionary<string, DataTable>();
        }

        //indexer
        public DataTable this[String tname]
        {
            get
            {
                if (this.Tables != null && this.Tables.Keys.Contains(tname))
                    return Tables[tname];
                return null;
            }
            set
            {
                if (this.Tables != null)
                    Tables[tname] = value;
            }
        }

        public static FakeDB GetFakeDB()
        {
            if (theFakeDB == null)
                theFakeDB = new FakeDB();
            return theFakeDB;
        }

        public Dictionary<String, DataTable> Tables;

        public DataTable GetTable(string name) 
        {
            if (Tables.Keys.Contains(name))
                return Tables[name];
            else
                return null;
        }

        public void SetTable(String name, DataTable table)
        {

                Tables[name] = table;
        }
    }

[javascript] console.log in IE

console.log has been a wonderful functionality in firebug/firefox. Sadly, there is no such feature in IE(i personally don’t like debugger). A simple logger for IE is implemented to make console.log works under IE

Snapshot:
console.log for IE

How to use:
include:

<link href="css/ctp.log.css" rel="stylesheet" type="text/css"/>
<!-- JSON.stringify is used for stringify object. Remove if don't need -->
<script language = "javascript" src="js/json2.js"></script>
<script language = "javascript" src="js/ctp.log.js">

use:

//use it as console.log in Firefox
<script>
for(var x =0; x<10; x++){
//logging before UI is rendered
console.log({"value":x, "time":new Date()});
}
</script>

Download:
from Sourceforge

[C++/CLI] How to throw a .NET exception

Recently cooperate with a Taiwan university lab. They use C++ to code a core library for our .NET developers to use. Here is how to throw a .NET exception in C++/CLI

public:
	int divide(int a, int b)
	{
		if(b==0)
		   throw gcnew System::Exception("It is a C++\CLI exception, can not divided by zero");
	}

[javascript]goto link later

here is the javascript code for preventing redirect when user clicks on a html anchor

javascript:

var url = {};

function addEvent(el, type, evt){
	if(el){
	if ( document.addEventListener ) {
	el.addEventListener( type, evt, false );
	} else if ( document.attachEvent ) {
	type="on"+type;
	el.attachEvent( type, evt );}}
}

function log4link0(el){
	addEvent(el, "click", function(evt){
		var lv = el.getAttribute("href");
		if(lv){
			/* record the clicked href */
			console.log("going to:"+lv);
			url.value = lv;}
		/* stop click event */
		if(evt){
			if (evt.stopPropagation ){
				evt.stopPropagation();
				evt.preventDefault();  
			}else{
				window.event.cancelBubble = true;
				window.event.returnValue = false;}
		}	
	});
}

function log4link(){
	var lks = document.getElementsByTagName("a");
	if(lks){
		var i=lks.length; while(i--){
			log4link0(lks[i]);}}
	/* register click event to element*/
	addEvent(document.getElementById("goto"), "click", function(){
		if(url && url.value)
			window.location = url.value;
	});
}

/* registr event on document load */
if ( document.addEventListener ) {
document.addEventListener( "DOMContentLoaded", log4link, false );
} else if ( document ) {
document.attachEvent("onreadystatechange",function(){ 
		if ( document.readyState === "complete" ) {log4link();}
});}

html:

<body>
<a href="http://www.google.com">Google</a>
<a href="http://www.yahoo.com">YAHOO!</a>
<a href="http://www.baidu.com">Baidu</a>
<a id="goto">continue</a>
</body>

i also “componentlized” this into a light-weight and independent javascript js library, called Go2Later

[C#] about Clone

 fooObj obj1 = new fooObj() { Name = "Aval" };
fooObj obj2 = (fooObj)obj1.Clone();
fooObj obj3 = (fooObj)obj1.CloneWithSerialization();
fooObj obj4 = obj1;
fooObj obj5 = (fooObj)obj1.ShallowCopy();
System.Diagnostics.Debug.WriteLine(obj1 == obj2);
System.Diagnostics.Debug.WriteLine(obj1 == obj3);
System.Diagnostics.Debug.WriteLine(obj1 == obj4);
System.Diagnostics.Debug.WriteLine(obj1 == obj5);
System.Diagnostics.Debug.WriteLine(obj1.Equals(obj2));
System.Diagnostics.Debug.WriteLine(obj1.Equals(obj3));
System.Diagnostics.Debug.WriteLine(obj1.Equals(obj4));
System.Diagnostics.Debug.WriteLine(obj1.Equals(obj5));

[Serializable]
    class fooObj: ICloneable, ISerializable
    {
        public String Name { get; set; }

        public override bool Equals(object obj)
        {
            if (obj == this)
                return true;
            else if (obj == null)
                return false;
            else 
                return (obj.GetType() == typeof(fooObj) && this.Name.Equals(((fooObj)obj).Name));
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public object Clone()
        {
            return new fooObj() { Name = this.Name };
        }

        public object MemberwiseClone()
        {
            return this.MemberwiseClone();
        }

        public object CloneWithAs()
        {
            return (new fooObj(){Name=this.Name}) as object;
        }

        public object ShallowCopy()
        {
            return this;
        }

        public object CloneWithSerialization()
        {
            using (Stream objects = new MemoryStream())
            {
                IFormatter formatter = new BinaryFormatter();
                formatter.Serialize(objects, this);
                objects.Seek(0, SeekOrigin.Begin);
                return formatter.Deserialize(objects);
            }
        }

        public fooObj() { }

        #region ISerializable Members

        [SecurityPermissionAttribute(SecurityAction.Demand,
          SerializationFormatter = true)]
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("Name", this.Name);
        }

        protected fooObj(SerializationInfo info, StreamingContext context)
        {
            this.Name = info.GetString("Name");
        }

        #endregion
    }