|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionI'm currently working with a complex AJAX control (Grid), and I have to concatenate a lot of In JavaScript, each Unfortunately, I have to support Internet Explorer 6 and Internet Explorer 7, and as everybody knows, this is a very big problem. BackgroundNormally, to optimize string concatenation, // The constructor initializes an Array
StringBuilderEx = function()
{
this._buffer = new Array();
}
StringBuilderEx.prototype =
{
// This method appends the string into an array
append : function(text)
{
this._buffer[this._buffer.length] = text;
},
// This method does concatenation using JavaScript built-in function
toString : function()
{
return this._buffer.join("");
}
};
We can optimize this class using a trick in JavaScript: every function call has a cost and we can use a function pointer to redirect // Assigns our class to Array class
var StringBuilderEx = Array;
// Using prototype I link function append to push and toString to join
Array.prototype.append=Array.prototype.push;
Array.prototype.toString=Array.prototype.join;
It seems like very strange code, but it is very quick because we jump 1 function call for every Using // It's very difficult to maintain
var sb = Sys.StringBuilder();
sb.append("<div style='width:");
sb.append(width);
sb.append("px;height:");
sb.append(height);
sb.append("px'></div>");
// It's more readable and easy to maintain
var sb = Sys.StringBuilder();
sb.append(String.format("<div style='width:{0}px;height:{1}px'></div>", width, height));
Unfortunately, the performance with I implemented two solutions to have
// Assign our class to Array class
var StringBuilderEx = Array;
// Using prototype I link function append to push
Array.prototype.append=Array.prototype.push;
// Used to convert arguments in array
Array.prototype._convertToArray=function(arguments)
{
if (!arguments)
return new Array();
if (arguments.toArray)
return arguments.toArray();
var len = arguments.length
var results = new Array(len);
while (len--)
{
results[len] = arguments[len];
}
return results;
};
// First solution using regular expression
Array.prototype.appendFormat=function(pattern)
{
var args = this._convertToArray(arguments).slice(1);
this[this.length]=pattern.replace(/\{(\d+)\}/g,
function(pattern, index)
{
return args[index].toString();
});
};
// Second solution using split and join
Array.prototype.appendFormatEx=function(pattern)
{
if (this._parameters==null)
this._parameters = new Array();
var args = this._convertToArray(arguments).slice(1);
for (var t=0,len=args.length;t<len;t++)
{
this._parameters[this._parameters.length]=args[t];
}
this[this.length]=pattern;
};
// Concatenate the strings using join
// (some lines of code are relay with second solution)
Array.prototype.toString=function()
{
var hasParameters = this._parameters!=null;
hasParameters = hasParameters && this._parameters.length>0;
if (hasParameters)
{
var values = this.join("").split('?');
var tempBuffer = new Array();
for (var t=0,len=values.length;t<len;t++)
{
tempBuffer[tempBuffer.length]=values[t];
tempBuffer[tempBuffer.length]=this._parameters[t];
}
return tempBuffer.join("");
}
else
{
return this.join("");
}
};
Using the CodeI wrote a custom class in JavaScript called
// Sample
var sb = new StringBuilderEx();
sb.append("Hello");
sb.appendFormat("Hello {0}!!! {1}", "World", "Bye");
sb.append("Hello ?!!! ?", "World", "Bye");
PerformanceI tested it on Vista with Internet Explorer 7: Run Tests Append Strings (20000)...
Run Tests Append Strings with Format (20000)...
I also tested it on Vista with Firefox 3.0b5: Run Tests Append Strings (20000)...
Run Tests Append Strings with Format (20000)...
Points of InterestI don't know if this is the fastest If someone knows of a way to have better performance, do not hesitate to contact me! History
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||