VBScript - JScript:谁怕谁?

来源:岁月联盟 编辑:exp 时间:2003-07-11
导读     
  在ASP环境下,VBScript和JScript哪种语言更好一些?本文测试这两种脚本语言完成常见操作所需要的时间,分析它们各自的长处和不足,并根据测试结果得出了一些值得关注的结论。
作者:仙人掌工作室 2000-12-19
   原文出处:http://www.asptoday.com/articles/20000920.htm
   选择方案体系需要考虑许多因素,往往关系到基于性能、容量、可维护性、职员经验、现有基础、个人爱好的成本优势分析。在典型的Microsoft/IIS实现中,这种考虑将继续深入扩展到ASP与大量不同的COM+组件协作时所担当的角色:在一个极端,注重性能远远超过编程和维护的方便程度,ASP只作为整合业务逻辑和用户界面的“粘合剂”;在另一个极端,注重编程和维护的方便程度超过性能,ASP本身用于实现许多业务逻辑。
   这种考虑甚至还可以继续深入一步,分析ASP的两种主要脚本语言(VBScript和JScript)相对而言各有哪些优缺点。从功能上看,赞成JScript的人可以说JScript提供了诸如更好的错误控制、继承、位操作以及一种客户端、服务器端基本通用的脚本语言等优点;反过来,赞成VBScript的人可以说VBScript也有自己的特点,如极其丰富的本地化能力,大小写无关的代码,更加简单直观的语法(当然,C程序员对这一点会有异议)。极端地说,我们不仅可以达到这样一个在同一网站不同ASP页面上分析两种语言各自优点的深度,而且在单个ASP页面之内也是如此!
   虽然有时在同一ASP页面内使用多种脚本语言能够简化编程,但它对性能不利。只需粗略地考虑一下这个问题,我们就知道运行这种ASP页面需要启动并缓存两个脚本引擎,极大地增加了开销。(而且,即使我们可以忽略性能问题,混合运用两种脚本语言本身就是不安全的,这是因为引擎缓冲机制将影响执行顺序。简而言之,如果开发者不小心的话,使用二个或以上脚本引擎的ASP页面可能不会顺序地执行。)
   本文所要深入研究的就是这个Windows 2000 / ASP3.0平台上VBScript对比JScript(以及VBScript加JScript)的性能问题。具体地说,本文将回答下列问题:
是否其中一种脚本语言要比另外一种快一点?
如果是,是在哪种情形之下以及为什么?
是否存在混合使用两种脚本语言可以减少执行时间的情形?(这种情形是否具有现实意义?)
如果某种语言总是比另外一种要快,两者速度差异的大小是否足以成为选择脚本语言的考虑因素?
   为回答这些问题,我们将比较8个典型例程的执行时间,这些例程用VBScript、JScript以及两者结合编写(两者结合是指,一种脚本语言作为ASP页面的主要语言(基本语言),由它来调用另一种脚本语言编写的内嵌函数)。这8个例程是:
字符串翻转(颠倒),
在一个字符串内搜索另一个字符串,
正则表达式模式匹配,
位移操作,
简单数学计算,
复杂数学计算,
数组初始化,
ADO记录集遍历。
   分析方法
   鉴于影响Web应用性能的因素是如此众多,而且真正困难的可能还在于配置出一个完全受控制的(也叫做“不现实的”)测试环境,本文的目的不是给出两种语言性能比较而言其差异的精确测度,而是给出各种编程方案下性能相对优势的可靠指示。
   这就是说,我们的目标不是为了知道JScript的正则表达式模式匹配操作要比VBScript的快23%,我们主要关心的是:是否存在这种差异,这种差异一般有多少明显,在什么样的情况下存在这种差异,以及为何会如此。
   本文只给出汇总(平均)数据。如果要查看更具体的数据,可以在data.xls找到原始的测试结果。data.xls可以从本文后面下载。
   测试是在一个桌面系统上进行,配置为:400MHz Celeron处理器,128 MB RAM,操作系统是Windows 2000 Server (5.00.2195),Web服务器是运行ASP 3.0 (asp.dll 5.0.2180.1)的IIS 5.0.2157.1。脚本引擎(JScript和VBScript)的版本是5.1.0.4615。测试期间系统所运行的服务减小到最小数量,而且为尽可能地保证测试环境的稳定性,这个最小数量一直保持不变。
   此外,考虑到IIS的默认脚本引擎设置可能造成测试结果的偏差,许多测试在两种可能的默认脚本引擎设置下进行。在所有测试过的方案中,该因素均不影响执行时间的先后和执行结果差异的大小。
   测试工具
   两个测试用的工具页面分别用VBScript(default.asp)和JScript(default-js.asp)编写。这两个页面具有同样的功能:让测试者选择一个ASP页面并指定执行该页面的次数,记录精确到千分之一秒的累计执行时间。(被执行页面由测试工具页面的Server.Execute调用)。


   同样,考虑到脚本引擎的初始化操作可能影响被调用页面的执行时间,许多测试方案都分别用两个测试工具页面在不同的IIS默认脚本引擎设置下进行了测试。和前面一样,在所有测试过的方案中该因素均不影响执行时间的先后和执行结果差异的大小。(然而,对于测试记录来说,即使IIS的默认脚本引擎设置成了JScript,用VBScript写的测试工具页面还是要比用JScript写的测试工具页面稍微快一点)。
   性能度量标准
   本文测试的性能度量标准是执行时间。执行时间四舍五入到最接近的毫秒值。如果测试工具页面多次执行测试页面(例如1000次的Server.Execute调用),执行时间起始位置在包围测试页面调用的“For loop”循环之前,执行时间的结束位置在循环结束后。
   基于VBScript的测试工具页面用Timer()函数计算执行时间,基于JScript的测试工具页面用JScript的Date对象计算执行时间。
我们选择了八个不同的测试例程(所有测试用到的代码已经在本文后面的下载ZIP文件中提供)。如果语言本身不具备某个方法或函数,则编写一个专用的方法。
   1.字符串翻转:进行这个测试不仅是因为它是一个很有代表性的操作,而且因为VBScript提供了内建的StrReverse()函数而JScript却没有等价的函数或方法。这为我们提供了一个很好的混合语言编程测试案例。本测试中被翻转的字符串是“String Reversal”。
   2.在一个字符串中搜索另一个字符串:VBScript和JScript本身都提供实现该任务的方法。我们用VBScript的InStr()函数和JScript的indexOf()方法在字符串“This is a sentence written for the sake of writing a sentence.”中查找字符串“ke”的起始位置。
   3.正则表达式模式匹配:虽然VBScript最近才加入了正则表达式支持,但这仍旧是一个很好的比较测试案例。JScript提供各种各样能够接受模式的String对象方法,使我们能够更灵活地进行处理;而VBScript没有这么灵活,必须在RegExp对象所界定的范围内进行。测试页面包含一个函数,这个函数接受字符串“Regular Expression Pattern Match”以及正则表达式“/(eg)|y|t{2,}/”,并返回匹配总次数。
   4.位移操作:JScript有位操作符而VBScript没有,这又是一个很好的比较测试案例。在进行这个测试的页面中将进行下列操作:97 < < 5 以及 -14 > > 2。
   5.简单数学计算:进行以下计算:18976.6754 + (-908.6) + 1475.211。
   6.复杂数学计算:测试页面包含这样一个函数,它根据两个点的坐标计算出它们之间的距离(英里)。VBScript的计算表达式为:

  Distance = Round(Sqr(((69.1 *(latA-latB))^2) +       ((69.1 * (Abs(lngA)-Abs(lngB)) * Cos(latB/57.3))^2)),1).

   7.数组初始化:只要出现对数组元素的访问,VBScript和JScript引擎都将创建整个数组的临时拷贝,这也是一个很好的测试案例。另外,JScript的数组同时也是带有许多方法和属性的对象,而VBScript中数组只是一个数组。这个测试通过For循环初始化一个有100,000个元素的数组,每个元素都被赋予循环计数器的值。
   8.ADO记录集遍历:这个测试使用的数据库是Access2000的“Northwind”数据库,程序通过ADO连接对象执行“SELECT * FROM ORDERS”命令获得一个ADO记录集。程序利用两个嵌套的循环:外部循环遍历记录,内部循环遍历每个记录的所有字段。这个测试案例之所以好,是因为JScript需要实例化一个Enumeration对象才能遍历对象集合,而VBScript只需要一个For Each ... Next循环就可以完成同样的任务。
上面的第一、三、四、六几种算法有一个共同特点:或者是其中一种语言独具某个功能,或者在正则表达式匹配和距离计算中,两种语言的差别非常大,足以成为一个很有意义的混合语言编程测试项目。这就为我们测试这些算法增加了两种方案:以VBScript作为基本语言调用内嵌的JScript函数;以JScript为基本语言调用内嵌的VBScript函数。测试代码举例如下(测试方案:字符串翻转,以JScript为基本语言,VBScript内嵌):

< %@Language=JScript% > < SCRIPT language="VBScript" runat="Server" > Function StrRevVB(strParm)   StrReverse(strParm)   End Function < /SCRIPT > < %   StrRevVB("String Reversal") % >

   所有其他例程都只包含语言本身提供的功能,这些例程只用纯VBScript和纯JScript版的代码测试。换句话说,对于任何情形的混合语言编程合理性测试来说,这些例程的价值都不大。
   第一组测试运行前六个例程,对于每一次运行,测试工具页面都要进行1000次对包含测试例程的ASP页面的调用(Server.Execute)。换句话说,如果某次运行调用了一个两种脚本语言都编写的页面1000次,则调用ASP引擎和各个脚本引擎的开销都达到1000次。虽然这种方法导致脚本引擎的开销影响测试结果,但我们获得的测试结果却更能反映出实际应用场合的效果。也就是说,虽然我们可以在单个页面之内完成1000次字符串翻转之类的操作,但更接近实际的是将这些代码和其他代码放入同一页面,然后让这个页面执行数千次。
   第二组测试运行全部八个例程,每次运行期间测试工具页面只执行测试页面1次,但测试页面本身包含循环。字符串翻转和简单数学计算都在它们各自的ASP页面内运行10,000次。模式匹配操作执行1,000次。字符串查找、距离计算以及两个位移操作(左移和右移)操作执行10,000次。在数组初始化测试中,程序声明一个100,000个元素的数组,然后通过For循环对它进行初始化并将计数器的值赋予各个元素。在记录集遍历测试中,程序通过While外循环遍历记录集(记录集包含830个记录),通过For Each ... Next内循环遍历单个记录的各个字段(每个记录有14个字段)。
   第二组测试提供的是这样一些方案,它们更加侧重于被测试例程本身的执行开销,从而更清楚地告诉我们两种脚本语言在执行时间方面的优缺点。
第一组测试的结果如下表所示。表中的数值是在不同方案下1000次ASP页面调用的平均执行时间,以秒计(每次执行ASP页面时测试例程执行一次)。 语言*** 字符串翻转* 字符串查找** 正则表达式模式匹配* 位移操作* 简单数学计算* 复杂数学计算** VB - VB 2.245 2.038 4.452 2.200 2.173 2.151 JS - JS 2.690 2.214 2.635 2.166 2.288 2.313 VB - JS 3.522 - 3.430 3.035 - 3.178 JS - VB 3.185 - 5.368 3.103 - 3.004
*运行96次,其中:24次是VBScript测试工具页面、IIS默认脚本语言VBScript;24次是JScript测试工具页面、IIS默认脚本语言VBScript;24次是VBScript测试工具页面、IIS默认脚本语言JScript;还有24次是JScript测试工具页面、IIS默认脚本语言JScript。为了减小次序带来的影响,第一、三、四、六测试例程的方案所运行的次序每次都经过改变。上表所显示的时间是96次运行的平均时间。所有细节数据都可以在下载包的data.xls文件内找到。
**使用VBScript测试工具页面运行24次,IIS脚本语言设置成VBScript(没有运行其他的测试工具页面和默认脚本语言的组合,因为在最初的运行中它们没有显示出任何次序或时间差异上的影响)。
***VB代表VBScript,JS代表JScript。两种语言中的前一种是页面的基本语言,第二种是内嵌代码所用的语言。内嵌代码不用于不需要使用它的场合。
   大多数测试结果的含义都非常明显,但应注意两个可能令人惊奇的结果。我们知道,JScript通过String对象的方法处理正则表达式,具有更好的灵活性,而VBScript需要实例化RegExp对象的开销。但令人惊奇的是,完全用VBScript编写的代码比以VBScript为基本语言、用内嵌JScript函数完成模式匹配操作的代码要慢。显然,实例化VBScript的RegExp对象需要非常可观的时间开销。
   第二个令人惊奇的地方是,虽然事实证明JScript的位操作总是要比VBScirpt的快,但在这些测试中两者的时间差异非常小。
   第二组测试的结果如下表所示。表中的数值表示不同方案下单个ASP页面的平均执行时间,以秒计(每执行一次ASP页面,测试例程运行多次)。 语言** 字符串翻转(1) 字符串搜索(3) 正则表达式模式匹配(2) 位移操作(3) 简单数学计算(1) 复杂数学计算(3) 数组初始化(1) 记录集遍历(4) VB - VB 0.120 0.346 2.250 0.200 0.287 0.328 2.182 0.524 JS - JS 2.589 0.998 0.138 0.036 0.426 0.499 9.120 0.641 VB - JS 3.066 - 0.221 0.890 - 1.310 - - JS - VB 0.472 - 2.363 0.769 - 0.671 - -
*每种情形用VBScript测试工具页面运行24次,IIS的默认脚本语言是VBScript(没有运行其他的测试工具页面和IIS默认脚本语言组合,因为在最初的运行中它们没有显示出任何次序或时间差异上的影响)。为了减小次序带来的影响,第一、三、四、六测试例程的方案所运行的次序每次都经过改变。上表所显示的是24次运行的平均时间,所有细节数据都可以在下载包的data.xls内找到。
**VB代表VBScript,JS代表JScript。两种语言中的前一种是页面的基本语言,第二种是内嵌代码所用的语言。内嵌代码不用于不需要使用它的场合。
  1. 100,000 次迭代
  2. 1,000次迭代
  3. 10,000次迭代
  4. 830个记录的外部循环,14个字段的内部循环(总共11,620次迭代)

   这些测试结果更清楚地证实了两种语言的区别所在。从数学计算的结果可以看出,VBScript在这方面要比JScript快——除了位移操作之外(JScript本身支持位移操作,而VBScript不支持)。
   两种语言最显著的区别在于字符串翻转、字符串搜索和数组初始化,所有这些测试项目中VBScript都占优势。
   字符串翻转操作是VBScript本身所支持的,在该项测试中两者差别尤其明显。在这个测试中,两者的差异之大使得采用内嵌VBScript StrReverse()函数也要比用JScript编写该函数快。
   在那些数据改动非常频繁使得手工构造数据失去现实意义的应用中,数据库记录集遍历是一种相当常见操作,因此,上述测试结果中VBScript和JScript在记录集遍历上的差异可能会给那些认为JScript优于VBScript的人一些警示。然而,这种执行时间上的差异也可以用如下事实来辩解,即我们为记录集中的每个记录分别实例化了一个Enumerator对象(总共达到了830次!)。
   从第一组测试的结果中已经可以看出,正则表达式模式匹配是JScript绝对优于VBScript的一个地方,所以这一组的测试结果并不令人奇怪。这里的测试结果证实了上一组的测试结果,但差异程度有所放大。
显然,我们可以从测试结果中得到这样一个结论:在一个注重性能的场合,混合运用多种脚本语言一般是没有意义的。如果要考虑两次模式匹配测试的结果差异,也应该看到每次迭代都创建了一个RegExp对象的实例。
   从这些测试结果中我们还可以得出另外两个重要的结论。首先,如果一种语言本身支持某个功能,直接使用该功能总是要比借用另外一种语言的功能快。第二,如果一种语言以对象形式实现了某种功能(比如VBScript的RegExp对象,JScript的Array和String对象),而第二种语言有更加基本的实现,则第二种语言在这方面速度较快。显然,创建对象实例的代价是相当高的。
   其它测试结果也显示出这一点。然而,这是否也证明:JScript作为一种更广泛地使用对象以及支持继承的语言,它必然要比VBScript慢?
   并不一定。如果我们是在实现一个N-层体系,复杂的业务逻辑总是被封装到组件里,ASP页面的脚本更主要地是提供整合业务对象和前端界面的“粘合剂”支持。换句话说,我们不太会过多地依赖于脚本本身或由脚本提供的对象。
   然而在有些场合我们却不能不用对象。以数组为例,无论是在VBScript还是JScript中,只要出现对数组元素的引用,内存中就要复制一个完整的数组。对于JScript来说,这意味着还要复制数组对象的全部属性。因此,如果程序大量地引用数组元素,使用JScript的代价显然比较高。
   附注
   我们应该还不会忘记第一轮的测试。这些案例往往不是在一个页面里运行数千次,而是单独地被调用数千次,此时执行时间上的差异就显得不那么明显。
   这样,下面这个理由可能会使我们草率地放弃本文的测试结果:如果性能很重要,那么我们就应该利用COM+所提供的对象池和二进制代码等优点,由此我们获得的好处将远远超过能够从一种脚本语言对于另一种脚本语言的优势之中获得的。如果我们可以认为方案体系的决策是一个性能(COM+)和编码/维护的方便性(脚本语言)之中二者择一的命题,那么这个理由确实是合理的。
   但在现实中不可能有无数的开发者拥有无限的技能,这一事实造成了上述两个极端之间根据历史条件、职员情况、开发时间等因素所作出的许多折衷和平衡。然而,在一些场合排除使用COM+并不意味着完全不再关注性能问题。如果由于某些原因COM+不适用,那么本文所提供的测试结果必将有助于您的决策。
   请从这里下载本文代码:http://www.asptoday.com/articles/images/20000920.zip