[发年终分]给JavaScript加上一个StringBuilder类
最近学习.net的时候,知道了.net中有StringBuilder类来方便频繁的字符串操作,想起java中也有StringBuffer类来创建可修改的字符串序列,何不给自己喜爱的JavaScript也加上这么个功能呢?于是祭起editplus,经过一番努力,终于有了下面的代码,写完之后上网搜了几个别人写的,感觉自己这个可以生成有规则的html代码的功能是别人没有的,所以贴出来给大家拍拍砖。大家有好的实现方法希望能贴出来。
我的电脑的测试结果(重复10000次):在ie7上平均为300/1300ms,在ff2上则为400/250ms。
代码如下:
//-------------------------------------------------
var StringBuilder = function(){
this._buffer = [];
this._arg1 = " ";
this._arg2 = " ";
if (arguments.length > 0) this._arg1 = String(arguments[0]);
if (arguments.length > 1) this._arg2 = String(arguments[1]);
}
StringBuilder.prototype.append = function(str){
// this._buffer.push(String(str)); //这个速度没有下面这个快
this._buffer[this._buffer.length] = String(str);
// this._buffer[this._buffer.length] = str; //去掉强制转换将更快,但是下面的表格输出就要修改了
}
StringBuilder.prototype.toString = function(){
return (this._arg2?this._arg1: " ") + this._buffer.join(this._arg2 + this._arg1) + this._arg2;
}
StringBuilder.prototype.clear = function(){
this._buffer = [];
}
StringBuilder.prototype.add = StringBuilder.prototype.append;
//example
var table = new StringBuilder( " <table border= '1 '> ", " </table> ");
var tr = new StringBuilder( " <tr> ", " </tr> ");
var td = new StringBuilder( " <td> ", " </td> ");
for (var i=1; i <10; i++)
{
for (var j=1; j <10; j++)
{
td.append(i*j);
}
tr.add(td);
td.clear();
}
table.append(tr);
document.write(table); // = table.toString()
//speed test
document.write( " <h2> 使用StringBuilder输出 </h2> ");
var st = new Date();
var t1 = new StringBuilder();
for (var i=0; i <10000; i++)
{
t1.append(i);
}
document.write(t1);
var et = new Date();
document.write( " <br /> 的时间为 " + (et-st) + "毫秒 <hr /> ");
t1.clear();
document.write( " <h2> 使用普通输出 </h2> ");
st = new Date();
var s = " ";
for (var i=0; i <10000; i++)
{
s += i;
}
document.write(s);
et = new Date();
document.write( " <br /> 的时间为 " + (et-st) + "毫秒 ");
s = " ";
//------------------------------------------------
[解决办法]
...
StringBuilder 是为了增加效率,,,
在 .NET String 是恒等的, 也就是更改不了的,
String 的 s+ 实际上并非是同一个 String 对象...
而是另外创建了一个 String 对象,
StringBuilder 是为了增加效率,
使用一个 对象 对字符串进行操作...
我不明白 你这个 StringBuilder 有什么实质意义
[解决办法]
up 支持原创
[解决办法]
mark
[解决办法]
接分!
[解决办法]
哈,早上好。。
[解决办法]
学习```````
[解决办法]
领年终分
[解决办法]
学习!
[解决办法]
document.write( " <h2> 使用普通输出 </h2> ");
var st = new Date, et, s = new Array, i;
for (i = 0 ; i < 10000 ; i ++) s[s.length] = i;
document.write(s.join( " "));
s.length = 0;
et = new Date;
document.write( " <br /> 的时间为 " + (et - st) + "毫秒 ");
这样会快好多的说。。
[解决办法]
this._buffer[this._buffer.length] = ( "object " != typeof str ? str : String(str));
改成这样也会快一些。。
被吹走。。。
[解决办法]
做的不错,考虑在toString后缓冲一下,下次toString没有改变的话返回原缓冲内容,可以提高一下速度
[解决办法]
呵呵。结分 ,实际应用中,用的不多,以前也写过 一个
拿来做普及js的面向对象的写法是个不粗的例子
[解决办法]
问题是这些都是与客户端配置有关,每个客户的客户端配置都不一样............这样钻牛角来提高客户端的速度有点本未倒置,我支持2楼的观点,提高代码速度应该是服务器端上的代码的事。
[解决办法]
好东西
MARK
[解决办法]
思路很不错
学习!
不过个人感觉用处不是很大
[解决办法]
不错,顶
[解决办法]
呵呵,领年终分。
[解决办法]
我操,狂昏不已!
楼主是否真的清除StringBuffer类的作用?
正如 btbtd(點點點...)(求职中, 联系:13435580019, 邱) 所说,人家.Net Java存在这个类名字刚好一样,或者Mfc的CString,Delphi的TString,都是为了“开发”效率!因为string 在计算机里面都是用ASCII码或者Unicode形式占内存空间的阿,人家封装一个StringBuffer是为了当处理“字符串”长度已发生变化的时候能够自动自动申请或者释放宝贵的内存的功能阿。您这个为的是什么啊,我怎么感觉既降低了开发效率,有降低了执行效率呢?JS 的String 对象原型已经是封装成了这样的功能,继续在JS的脚本层面上作这类封装不就是“画蛇添足”么?很可笑的想法啊,如果仅仅是出于研究好奇,无妨,但是还含着“提高效率”,我就觉得无知了。
给你一个我自己实现的的String类,也就是你说的StringBuffer类,.Net我不会,去掉了大部分功能,只保留了和你那个相同功能的地方,真正的学习一下吧。
class MyString
{
static const char *s_pNullStr;
protected:
char *m_pData;
int m_Length;
int m_BufSize;
void newbuf(const char *m_pData,int len);
public:
MyString();
~MyString();
MyString(const char *lpvalue);
void Empty(void);
void setValue(LPCTSTR str);
void Insert(long Pos,char c);
void operator = (const char *buf);
void operator += (const char *strg);
BOOL operator == (const char *str);
BOOL operator != (const char *str);
friend MyString operator + (const MyString & Str1, const MyString & Str2);
};
#define EXPENTSIZE 8
MyString::MyString()
{
m_pData=NULL;
m_BufSize=m_Length=0;
}
MyString::MyString(const char *lpvalue)
{
m_pData=NULL;
m_BufSize=m_Length=0;
setValue(lpvalue);
}
MyString::~MyString()
{
Empty();
}
inline void MyString::Empty()
{
if (m_pData!=NULL) delete m_pData;
m_pData=NULL;
m_BufSize=m_Length=0;
}
void MyString::newbuf(const char *lpvalue,int len)
{
if (len <0) len=0;
Empty();
m_BufSize=len+EXPENTSIZE;
m_pData = new char[m_BufSize+2];
if (lpvalue && len> 0)
{
int cpyl=strlen(lpvalue);
if (cpyl> 0) {
cpyl=min(cpyl,len);
memcpy(m_pData,lpvalue,cpyl);
m_pData[cpyl]=0;
m_Length=cpyl;
}
}
else {
*m_pData=0;
}
}
void MyString::Insert(long Pos,char c)
{
if (Pos <0) return;
long maxLen=(Pos <m_Length)?(m_Length+1):(Pos+1);
if ( maxLen> =m_BufSize)
{
char *lpold=m_pData;
m_pData=NULL;
newbuf(lpold,maxLen+1);
if (lpold) delete []lpold;
}
if (Pos <m_Length){
memmove(m_pData+Pos+1,m_pData+Pos,m_Length-Pos+1);
}
*(m_pData+Pos)=c;
m_Length+=1;//strlen(m_pData);
*(m_pData+m_Length)=0;
}
void MyString::operator = (const char *lpvalue)
{
setValue(lpvalue);
}
void MyString::operator += (const char *strg)
{
Insert(m_Length,strg);
}
MyString operator + (const MyString & Str1, const MyString & Str2)
{
MyString TempStr(Str1);
TempStr+=Str2;
return TempStr;
}
BOOL MyString::operator == (const char *str)
{
if (m_pData==NULL || str==NULL || m_Length <1) return FALSE;
return (strcmp(m_pData,str)==0);
}
BOOL MyString::operator != (const char *str)
{
return !(*this==str);
}
void MyString::setValue(LPCTSTR lpvalue)
{
Empty();
if (lpvalue==NULL) return;
newbuf(lpvalue,strlen(lpvalue));
}
实现了你的基本功能.注意#define EXPENTSIZE 8 这行,这才是为了提高效率做的事情,也是所谓字符串缓冲区(察看一下MSDN你就明白了http://msdn2.microsoft.com/zh-cn/library/system.text.stringbuilder(VS.80).aspx),如果你认为现在流行的计算机配置都是1G ram,那么你大可把它设置成64,不是每一次字符串变化都需要重新申请内存的,那很慢的。
每次看到JS里面某些人这这些毫无意义,并且本身根本不了解JS或者程序仅仅是扛着几颗五角星大喊特喊提高效率说一些“人家都听不明白的专用词”糊弄不懂得人,我都觉得可笑。
[解决办法]
mark...
[解决办法]
JF
[解决办法]
llrock(百乐宝||昨夜星辰) :老僵尸出土了。
[解决办法]
年终领分了
------解决方案--------------------
骂人有什么好的?
javascript的string也是非可变类,你搞清了没有
你认为n个字符串用加号连起来和使用join这个内嵌函数连起来这两种方法会具有相同的效率么?
楼主连试验的结果都有,真搞不清你们为什么要说效率没有提高?
一群纸上谈兵的家伙。。。。。
本身这个想法就很有特色,尤其是对javascript这种有时候需要大量拼接字符串的脚本语言
还有你那个MyString的+号运算的效率不好
完全可以先分好缓冲区,再拷贝字符串,没必要先生成字符串,再伸缩缓冲区拷入另一个字符串
不能原地工作的操作在这种类里面最好不要建议用户使用
[解决办法]
jf~~
[解决办法]
我觉得这个比那些老问HelloWorld的好多了
这个论坛现在有人问的问题让人哭笑不得
讨论一下这些问题还让人有点眼前一亮的感觉
[解决办法]
扣了红包,同情你一下。。。。
[解决办法]
JF
[解决办法]
z支持支持
[解决办法]
虽然意义不大,但是有这想法我觉得好啊,比问傻问题和拿千年前的旧教程来贴的要好得多
[解决办法]
up
[解决办法]
up~
[解决办法]
狂日,楼上大家讲得是什么啊,我不懂啊,真不懂,什么是StringBuffer类啊,我是半路出家,基础类的东东一点不懂(正则也不懂),我只知道到目录为止碰到的JS问题我都能解决(甭管效率),呵呵,也可能是我没碰到过有什么深度的问题吧。
我认为,能解决问题的方法就是好方法