|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
asp,你就只能等着微软给你解决,它不乐意你就只好悲催。而且asp跑在windows服务器上,windows服务器跟linux比起来简直弱爆了!程序|字符串 择要:年夜多半ActiveServerPages(ASP)使用程序都要经由过程字符串联接来创立出现给用户的HTML格局的数据。本文对几种创立此HTML数据流的办法举行了对照,在特定情形下,某些办法在功能方面要优于其他办法。本文假定您已具有必定的ASP和VisualBasic编程方面的常识。简介
编写ASP页面时,开辟职员实践上是创立一个格局化的文本流,经由过程ASP供应的Response工具写进Web客户端。创立此文本流的办法有多种,而您选择的办法将对Web使用程序的功能和可缩放性发生很年夜影响。良多次,在我匡助客户优化其Web使用程序的功能时,发明个中一个对照无效的办法是变动HTML流的创立体例。本文将先容几种经常使用手艺,并测试它们对一个复杂的ASP页面的功能所发生的影响。
ASP计划很多ASP开辟职员都遵守优秀的软件工程准绳,尽量地将其代码模块化。这类计划一般利用一些包括文件,这些文件中包括对页面的特定不一连部分举行格局化天生的函数。这些函数的字符串输入(一般是HTML表格代码)能够经由过程各类组合创立一个完全的页面。某些开辟职员对此办法举行了改善,将这些HTML函数移到VisualBasicCOM组件中,但愿充实使用已编译的代码供应的分外功能。只管这类计划办法很不错,但创立构成这些不一连HTML代码组件的字符串所利用的办法将对Web站点的功能和可缩放性发生很年夜的影响,不管实践的操纵是在ASP包括文件中实行仍是在VisualBasicCOM组件中实行。
字符串联接请看以下WriteHTML函数的代码片段。名为Data的参数只是一个字符串数组,个中包括一些要格局化为表格布局的数据(比方,从数据库前往的数据)。
FunctionWriteHTML(Data)
DimnRepFornRep=0to99
sHTML=sHTML&vbcrlf_
&"<TR><TD>"&(nRep+1)&"</TD><TD>"_
&Data(0,nRep)&"</TD><TD>"_
&Data(1,nRep)&"</TD><TD>"_
&Data(2,nRep)&"</TD><TD>"_
&Data(3,nRep)&"</TD><TD>"_
&Data(4,nRep)&"</TD><TD>"_
&Data(5,nRep)&"</TD></TR>"Next
WriteHTML=sHTML
EndFunction这是良多ASP和VisualBasic开辟职员创立HTML代码经常用的办法。sHTML变量中包括的文本前往到挪用代码,然后利用Response.Write写进客户端。固然,这还能够暗示为间接嵌进不包括WriteHTML函数的页面的相似代码。此代码的成绩是,ASP和VisualBasic利用的字符串数据范例(BSTR或Basic字符串)实践上没法变动长度。这意味着每当字符串长度变动时,内存中字符串的原始暗示情势都将遭到损坏,并且将创立一个包括新字符串数据的新的暗示情势:这将增添分派内存息争除分派内存的操纵。固然,ASP和VisualBasic已为您办理了这一成绩,因而实践开支不会当即展现出来。分派内存息争除分派内存请求基础运转时期码排除各个公用锁定,因而必要大批开支。当字符串变得很年夜而且有年夜块内存要被疾速一连地分派息争除分派时,此成绩变得尤其分明,就像在年夜型字符串联接时代呈现的情形一样。只管这一成绩对单用户情况的影响不年夜,但在服务器情况(比方,在Web服务器上运转的ASP使用程序)中,它将招致严峻的功能和可缩放性成绩。上面,我们回到上述代码片断:此代码中要实行几个字符串分派操纵?谜底是16个。在这类情形下,“&”运算符的每次使用都将招致变量sHTML所指的字符串被损坏和从头创立。后面已提到,字符串分派的开支很年夜,而且跟着字符串的增年夜而增添,因而,我们能够对上述代码举行改善。
快速的办理计划有两种办法能够减缓字符串联接的影响,第一种办法是实验减小要处置的字符串的巨细,第二种办法是实验削减实行字符串分派操纵的数量。请拜见上面所示的WriteHTML代码的订正版本。
FunctionWriteHTML(Data)
DimnRep
FornRep=0to99
sHTML=sHTML&(vbcrlf_
&"<TR><TD>"&(nRep+1)&"</TD><TD>"_
&Data(0,nRep)&"</TD><TD>"_
&Data(1,nRep)&"</TD><TD>"_
&Data(2,nRep)&"</TD><TD>"_
&Data(3,nRep)&"</TD><TD>"_
&Data(4,nRep)&"</TD><TD>"_
&Data(5,nRep)&"</TD></TR>")Next
WriteHTML=sHTML
EndFunction乍一看,大概很难发明这段代码与上一个代码示例的不同。实在,此代码只是在sHTML=sHTML&后的内容表面加上了括号。这实践上是经由过程变动优先按次,来减小年夜多半字符串联接操纵中处置的字符串巨细。在最后的代码示例中,ASP编译器将检察等号右侧的表达式,并从左到右举行盘算。了局,每次反复都要举行16个毗连操纵,这些操纵针对不休增加的sHTML举行。在新版本中,我们提醒编译器变动操纵按次。如今,它将按从左到右、从括号内到括号外的按次盘算表达式。此手艺使得每次反复包含15个毗连操纵,这些操纵针对的是不会增加的较小字符串,只要一个是针对不休增加的年夜的sHTML。显现了这类优化办法与尺度毗连办法在内存利用形式方面的对照。
:尺度毗连与加括号毗连在内存利用形式方面的对照
在特定情形下,利用括号能够对功能和可缩放性发生非常明显的影响,后文将对此举行进一步的申明。
StringBuilder我们已找到懂得决字符串联接成绩的快速办法,在多半情形下,此办法能够到达功能和投进的最好均衡。可是,假如要进一步进步构建年夜型字符串的功能,必要接纳第二种办法,即削减字符串分派操纵的数量。为此,必要利用StringBuilder。StringBuilder是一个类,用于保护可设置的字符串缓冲区,办理拔出到此缓冲区的新文本片段,并仅在文本长度超越字符串缓冲区长度时对字符串举行从头分派。Microsoft.NET框架收费供应了如许一个类(System.Text.StringBuilder),并倡议在该情况下举行的一切字符串联接操纵中利用它。在ASP和传统的VisualBasic情况中,我们没法会见此类,因而必要自行创立。上面是利用VisualBasic6.0创立的StringBuilder类示例(为简便起见,省略了毛病处置代码)。
OptionExplicit默许的缓冲区初始巨细和增加系数
PrivateConstDEF_INITIALSIZEAsLong=1000
PrivateConstDEF_GROWTHAsLong=1000缓冲区巨细和增加
Privatem_nInitialSizeAsLongPrivatem_nGrowthAsLong缓冲区弛缓冲区计数器
Privatem_sTextAsString
Privatem_nSizeAsLongPrivatem_nPosAsLong
PrivateSubClass_Initialize()设置巨细和增加的默许值
m_nInitialSize=DEF_INITIALSIZE
m_nGrowth=DEF_GROWTH初始化缓冲区
InitBufferEndSub设置初始巨细和增加数目
PublicSubInit(ByValInitialSizeAsLong,ByValGrowthAsLong)
IfInitialSize>0Thenm_nInitialSize=InitialSize
IfGrowth>0Thenm_nGrowth=Growth
EndSub初始化缓冲区
PrivateSubInitBuffer()
m_nSize=-1
m_nPos=1EndSub增年夜缓冲区
PrivateSubGrow(OptionalMinimimGrowthAsLong)初始化缓冲区(若有需要)
Ifm_nSize=-1Then
m_nSize=m_nInitialSize
m_sText=Space$(m_nInitialSize)
Else只是增加
DimnGrowthAsLong
nGrowth=IIf(m_nGrowth>MinimimGrowth,
m_nGrowth,MinimimGrowth)
m_nSize=m_nSize+nGrowth
m_sText=m_sText&Space$(nGrowth)
EndIfEndSub将缓冲区巨细调剂到以后利用的巨细
PrivateSubShrink()
Ifm_nSize>m_nPosThen
m_nSize=m_nPos-1
m_sText=RTrim$(m_sText)
EndIfEndSub增加单个文本字符串
PrivateSubAppendInternal(ByValTextAsString)
If(m_nPos+Len(Text))>m_nSizeThenGrowLen(Text)
Mid$(m_sText,m_nPos,Len(Text))=Text
m_nPos=m_nPos+Len(Text)EndSub增加一些文本字符串
PublicSubAppend(ParamArrayText())
DimnArgAsLong
FornArg=0ToUBound(Text)
AppendInternalCStr(Text(nArg))
NextnArgEndSub前往以后字符串数据并调剂缓冲区巨细
PublicFunctionToString()AsString
Ifm_nPos>0Then
Shrink
ToString=m_sText
Else
ToString=""
EndIf
EndFunction扫除缓冲区偏重新初始化
PublicSubClear()
InitBuffer
EndSub此类中利用的基础准绳是,在类级别将变量(m_sText)用作字符串缓冲区,并利用Space$函数以空格字符添补此缓冲区以将其设置为特定的巨细。假如要将更多文本与现有文本毗连在一同,则在反省缓冲区的巨细足以寄存新文本后,利用Mid$函数在准确地位拔出文本。ToString函数将前往以后存储在缓冲区中的文本,并将缓冲区的巨细调剂为可以包容此文本的准确长度。利用StringBuilder的ASP代码以下所示:
FunctionWriteHTML(Data)
DimoSBDimnRep
SetoSB=Server.CreateObject("StringBuilderVB.StringBuilder")用巨细和增加系数初始化缓冲区
oSB.Init15000,7500
FornRep=0to99
oSB.Append"<TR><TD>",(nRep+1),"</TD><TD>",_
Data(0,nRep),"</TD><TD>",_
Data(1,nRep),"</TD><TD>",_
Data(2,nRep),"</TD><TD>",_
Data(3,nRep),"</TD><TD>",_
Data(4,nRep),"</TD><TD>",_
Data(5,nRep),"</TD></TR>"Next
WriteHTML=oSB.ToString()
SetoSB=Nothing
EndFunction利用StringBuilder必要必定的开支,由于每次利用此类时都必需创立它的实例,而且在创立第一个类实例时必需加载包括此类的DLL。对StringBuilder实例举行分外办法挪用时也必要开支。利用加括号的“&”办法时,StringBuilder怎样实行取决于多个要素,包含毗连的数量、要构建的字符串的巨细和选择的StringBuilder字符串缓冲区的初始化参数的功能。请注重,在多半情形下,将缓冲区中所需的空间量估量得略高一些要远远好过让其不休增加。
内置办法ASP包括一种十分快速的创立HTML代码的办法,只需屡次挪用Response.Write。Write函数利用隐式优化的字符串缓冲区,此缓冲区可以供应十分优异的功能特征。修正后的WriteHTML代码以下所示:
FunctionWriteHTML(Data)
DimnRep
FornRep=0to99
Response.Write"<TR><TD>"Response.Write(nRep+1)
Response.Write"</TD><TD>"
Response.WriteData(0,nRep)
Response.Write"</TD><TD>"
Response.WriteData(1,nRep)
Response.Write"</TD><TD>"Response.WriteData(2,nRep)
Response.Write"</TD><TD>"
Response.WriteData(3,nRep)
Response.Write"</TD><TD>"
Response.WriteData(4,nRep)
Response.Write"</TD><TD>"
Response.WriteData(5,nRep)
Response.Write"</TD></TR>"
Next
EndFunction固然这段代码极可能为我们供应最好的功能和可缩放性,但在某种水平上已损坏了封装,由于如今会将函数外部的代码间接写进Response流,以是挪用代码损失了必定水平的把持权。别的,挪动此代码(比方,移进COM组件)将变得加倍坚苦,由于此函数与Response流存在依附干系。
测试下面提到的四种办法分离经由过程一个复杂的ASP页面(包括一个由假造字符串数组供应数据的单个表格)举行了测试。我们利用ApplicationCenterTest?(ACT)从单个客户端(Windows?XPProfessional,PIII-850MHz,512MBRAM)针对100Mb/sec收集中的单个服务器(Windows2000AdvancedServer,双PIII-1000MHz,256MBRAM)实行了测试。ACT设置为利用5个线程,以摹拟5个用户毗连至网站时的负载。每一个测试都包含20秒预热工夫和随后的100秒负载工夫,在负载时代创立了尽量多的哀求。经由过程变动主表格轮回中的反复次数,针对分歧数量的毗连操纵反复运转测试,如WriteHTML函数中的代码片段所示。运转的每一个测试都利用上文提到的四种分歧的办法实行。
了局上面的一系列图表显现了各类办法对全部使用程序吞吐量的影响,和ASP页面的呼应工夫。经由过程这些图表,我们能够懂得使用程序撑持的哀求数量,和用户守候页面下载至扫瞄器所需的工夫。
表1:利用的毗连办法缩写的申明
办法缩写申明RESP内置Response.Write办法CAT尺度毗连(“&”)办法PCAT加括号的毗连(“&”)办法BLDRStringBuilder办法在摹拟典范ASP使用程序事情负荷方面,此测试与实践情形相差甚远,从表2中能够分明看到,即便反复420次,此页面仍不是出格年夜。如今良多庞大的ASP页面在这些数字上都是对照高的,设置有大概超越此测试局限的限定。
表2:测试示例的页面巨细和毗连数量
反复次数毗连数量页面巨细(以字节为单元)152402,667304804,917457207,167609609,417751,20011,6671201,92018,5391802,88027,8992403,84037,2593004,80046,6193605,76055,9794206,72062,219
:吞吐量了局图
从的图表中能够看到,正如我们所预期的,多重Response.Write办法(RESP)在测试的全部反复测试局限中为我们供应了最好的吞吐量。但使人惊奇的是,尺度字符串联接办法(CAT)的下落云云伟大,而加括号的办法(PCAT)在反复实行300屡次时功能仍旧要好良多。在约莫反复220次的地方,字符串缓存带来的功能进步凌驾了StringBuilder办法(BLDR)固有的开支,在这一点以上,在此ASP页面中利用StringBuilder所需的分外开支是值得的。
:呼应工夫了局图
:省略CAT的呼应工夫了局图
和中的图表显现了按“到第一字节的工夫”丈量的呼应工夫(以毫秒为单元)。由于尺度字符串联接办法(CAT)的呼应工夫增添过快,以是又供应了未包含此办法的图表(),以便剖析其他办法之间的差别。有一点值得注重,多重Response.Write办法(RESP)和StringBuilder办法(BLDR)随反复次数的增添出现一种近似线性的增加,而尺度毗连办法(CAT)和加括号的办法(PCAT)则在凌驾必定的阈值以后入手下手敏捷增添。
小结<P>本文侧重报告了怎样在ASP情况中使用分歧的字符串构建手艺,这些内容一样合用于一切利用VisualBasic代码创立年夜型字符串的计划,比方手动创立XML文档。以下准绳能够匡助您断定哪一种办法最合适您的必要。
- 起首实验加括号的“&”办法,特别是在处置现有代码时。这类办法对代码布局的影响微不足道,但您会发明使用程序的功能将明显加强,乃至会超越预定方针。在不损坏所需的封装级其余情形下利用Response.Write。利用此办法,能够制止不用要的内存内字符串处置,从而供应最好的功能。
- 利用StringBuilder构建真正年夜型或毗连数量较多的字符串。
只管您大概未看到本文所示的这类功能增加,但我已在实在的ASPWeb使用程序中利用了这些技能,只必要很少的分外投进就能够在功能和可缩放性方面取得很年夜的进步。
我想详细了解ASP整站代码与PSP整站代码有什么优缺点,那个更好,更安全,更用容易维护,和管理。。。 |
|