65.9K
CodeProject 正在变化。 阅读更多。
Home

如何加速我们的VB.NET Web应用程序

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.61/5 (11投票s)

2007 年 5 月 4 日

9分钟阅读

viewsIcon

61795

提高 Web 应用程序效率的一些技巧。

引言

我们可以通过一些简单的实践来提高Web应用程序的性能。本文将介绍一些可以提高代码性能的技巧。

如何加速我们的VB.NET Web应用程序

  1. 使用Return语句从函数返回值在某些情况下,如果使用新的Return语句从函数返回值,而不是将值赋给与函数本身同名的变量(如在VB6中),编译器可以生成更好的代码。
  2. 在进行不区分大小写的字符串比较时,请尝试使用String.CompareOrdinal而不是String.Compare方法或=和<>运算符。.
    Compare方法以对本地文化敏感的方式比较字符串,因此它必须将每个字符的Unicode代码转换为一个数字值,该值反映其在当前文化字母表中的位置。例如,Compare方法认为小写字符“b”紧随大写字符“A”之后,并在大写字符“B”之前,即使“A”和“B”字符在Unicode字符集中是连续的。这种转换活动需要时间和消耗CPU周期,因此您会发现VB.NET在比较字符串方面不如VB6高效。使用=运算符和其他比较运算符根本没有帮助,因为它们在幕后映射到Compare方法,因此这些运算符也存在相同的性能损失。

    如果您只关心检查两个字符串是否包含相同的字符(在区分大小写的比较中),您可以通过使用CompareOrdinal共享方法来加速代码。此方法比Compare方法(或=运算符)快3-4倍,因为它只是扫描两个字符串并比较每个字符的Unicode数字代码。
  3. StringBuilder比&和+更快
    试试这个

    dim Var1
    Var1= "This "
    Var1= Var1& "is old "
    Var1= Var1& "string "
    Var1= Var1& "concatenation."


    实际上创建了四个变量。每行一个,然后为创建的覆盖变量重新分配内存。内存管理不佳。


    如果您以相同的方式执行字符串连接

    Dim someString As New String()
    someString &= "This "
    someString &= "is old "
    someString &= "string "
    someString &= "concatenation."
    


    您仍然会遇到相同的性能下降。

    但是,.NET中提供了一个名为StringBuilder的新类。它动态地将内存块分配给同一个对象(StringBuilder本身,而不是字符串)...在每次连接时扩展它,从而获得更好的性能。它位于System.Text命名空间中,以下是它的使用方法

    Imports System.Text
    
    Dim newStringBuilder As New StringBuilder()
    newStringBuilder.Append("This ")
    newStringBuilder.Append("is new ")
    newStringBuilder.Append("string ")
    newStringBuilder.Append("concatenation.")
    
    Dim myString As New String(newStringBuilder.toString())
    


    这样它们实际上是两个独立的对象,并且字符串构建器在构建字符串时负责内存管理,然后您只需调用StringBuilder的.ToString()方法将结果输出到新的字符串对象,从而只调用一次新的字符串(),并避免其效率低下的陷阱。
  4. 通过使用正则表达式加速搜索和替换字符串操作。例如,此代码显示句子中的所有单个单词
    ' This code requires the following imports
    ' Imports System.Text.RegularExpressions
    
    Dim s As String = "Hi there, how are you?"
    Dim re As New Regex("\w+")
    Dim m As Match
    For Each m In re.Matches(s)
    Console.WriteLine(m.Value)
    Next 
  5. 将尽可能多的代码移到循环之外
  6. 如果可能,使用循环展开循环展开可以消除一些比较和跳转指令。(比较和跳转指令用于创建循环,您在Visual Basic中看不到它们,它们是您在ASM中学习的幕后内容。)它还利用了现代CPU可以一次获取多条指令的能力。简而言之,通过展开循环,您可以获得很好的速度提升。但是关于循环展开,我们需要了解一些事情。现代计算机上最大的瓶颈是内存。因此,像Intel和AMD这样的CPU设计师通过在他们的CPU上使用缓存来解决这个问题。这基本上是一个内存位置,CPU访问它的速度比标准内存快得多。您希望展开的循环能够适应该缓存,如果不能,它可能会减慢您的代码。因此,您可能需要在展开循环时尝试gettickcount。示例循环
    代码
    For i = 1 To 100
    b = somefun(b)
    Next i

    展开示例
    代码
    For i = 1 To 100 step 2
    b = somefun(b)
    b = somefun(b)
    Next i 
  7. 如果可能,避免除法。除法指令是CPU上最昂贵的指令之一,如果不是最昂贵的。乘法比除法更快!
    代码
    B = 19 / 2

    比这慢
    代码
    b = 19 * 0.5
  8. 在嵌套的条件分支(如select case和嵌套的if语句)中,将最可能为真的条件放在嵌套的前面,将最不可能的条件放在最后。
  9. 减少通用表达式。有时您有两个不同的变量使用相同的计算的一部分。不要为这两个变量执行整个计算,而是消除冗余计算。示例
    代码
    x = a * b + c
    y = a * b + d
    
    比这慢
    代码
    t = a * b
    x = t + c
    y = t + d

    如果您在循环中使用冗余的昂贵计算,尤其如此。
  10. 使用长整型或整型进行计算。长整型是32位数字,在32位处理器上更自然。避免使用其他变量,如double、single等
  11. 在循环内部使用内联函数。不要调用函数,而是将代码放入循环中。如果在一个程序中重复使用足够的循环,这将使程序更大,并且只应在关键位置进行。原因在于调用函数的开销。在程序调用函数之前,它必须将一些东西压入堆栈。至少它会压入指令指针(IE:返回地址)。内存访问很慢,所以我们希望在关键位置避免这种情况。
  12. 避免在循环中使用属性。属性的访问速度比变量慢得多,因此请改用变量。
    代码
    for i = 1 to 50
    text1.text = text1.text + b(i)
    next i
    is slower then
    Code:
    for i = 1 to 50
    strbuffer = strbuffer + b(i)
    next i
    text1.text = strbuffer.
    这也适用于用户定义的属性。
  13. 从磁盘加载所有需要的数据。不要一次加载一个文件,而是同时加载所有文件。这将避免用户未来的延迟。
  14. 充分利用计时器控件。您可以在等待用户时进行后台处理。利用这段时间预取数据、进行必要的计算等。
  15. 尽量减少对象中的点表示法您在对象中使用的每个点都会使Visual Basic进行一次调用。
    代码
    Myobject.one.two.three
    
    比这慢
    代码
    Myobject.one </li>
  16. 一次性分配足够的内存。当您创建一个动态数组并且想要添加尚未分配的元素时,请确保为所有元素分配足够的内存,而不是一次一个地分配。如果您不知道需要多少,请将已分配的内存乘以2。分配内存是一个昂贵的过程。
  17. 避免在循环中使用内置函数。如果您的算法在循环中需要字符串的长度。请确保将字符串的大小缓存到缓冲区中,而不是在循环的每次迭代中都调用len()函数。
    代码
    for i = 1 to 100
    sz = len(string)
    'Do processing
    next i
    instead
    Code:
    sz = len(string)
    for i = 1 to 100
    'Do Processing with sz
    next i 
    
    
    
    Dim x as integer,a as integer
    x=listbox.count-1
    for a= 0 to x
    next a
    
    此代码比这更快

    Dim a as integer
    for a= 0 to listbox.count-1
    next a
    
    因为在第二种情况下,每次循环迭代都必须计算该值,这需要时间。
  18. 减少数据库访问次数
  19. 不要在代码中依赖异常。由于异常会导致性能显著下降,因此您不应将其用作控制正常程序流的方法。如果可以在代码中检测到会导致异常的条件,请这样做。在处理该条件之前,不要捕获异常本身。常见场景包括检查null、为将解析为数值的String赋值,或在应用数学运算之前检查特定值。
  20. 适当使用公共语言运行时(CLR)的垃圾回收器和自动内存管理。请注意不要为每个请求分配过多的内存,因为垃圾回收器将不得不更频繁地进行更多的工作。此外,不要拥有指向对象的冗余指针,因为它们会使对象保持活动状态,并尽量避免使用带有Finalize方法的对象,因为它们会在稍后时间带来更多工作。特别是,切勿在调用Finalize时释放资源,因为资源可能会消耗内存直到垃圾回收器运行它。最后一个问题通常会破坏Web服务器环境中的性能,因为在等待Finalize运行时很容易耗尽给定资源的可用性。
  21. 使用HttpServerUtility.Transfer方法在同一应用程序的不同页面之间进行重定向。在页面中使用此方法,结合Server.Transfer语法,可避免不必要的客户端重定向。
  22. 使用SQL Server存储过程进行数据访问。在.NET Framework提供的所有数据访问方法中,基于SQL Server的数据访问是构建高性能、可伸缩Web应用程序的推荐选择。使用托管的SQL Server提供程序时,通过使用编译的存储过程而不是即席查询,可以获得额外的性能提升。
  23. 要在不提交表单的情况下导航到URL,请使用HyperLink控件;要提交表单然后导航,请使用LinkButton。对于网页访问者来说,HyperLink控件和LinkButton控件看起来是相同的。但是,它们的功能存在显著差异。当用户点击HyperLink控件时,它会立即导航到目标URL。表单不会提交到服务器。LinkButton控件首先将表单提交到服务器,然后导航到URL。如果您需要在转到目标URL之前进行任何服务器端处理,请使用LinkButton。另一方面,如果不需要进行服务器端处理,则不要浪费一次往返,并使用HyperLink控件。
  24. 保持Option Strict和Option Explicit开启保持Option Strict和Option Explicit开启具有性能优势。Option Explicit On强制显式声明变量。如果没有显式声明,编译器会生成装箱代码。因此,值类型变量会作为引用类型移动到堆中。这将影响性能。

    Option Strict On强制显式类型转换。隐式类型转换会导致后期绑定。这是非常昂贵的。通过保持Option Strict On,程序员必须使用显式类型转换,这将导致早期绑定。但是,为了向后兼容,VB.NET很难保持Option Strict Off。在编码之前,请确保Option Strict和Explicit开启。

  25. 通过提供客户端脚本来避免过多的服务器往返大多数事情,如输入验证,可以从服务器端移到客户端。大多数应用程序典型的服务器端用途是数据存储和检索。因此,将可以在客户端执行的代码移到客户端。这样我们就可以避免过多的服务器往返。

  26. 使用Page.IsPostback避免额外工作某些工作,如控件初始化、数据获取等,只需要执行一次。通过使用Page.IsPostback来避免这种情况。

  27. 禁用 Session 状态不使用时并非所有应用程序或页面都需要按用户会话状态。如果不需要,请完全禁用它。这可以通过页面级指令轻松实现,例如以下内容:

    <%@ Page EnableSessionState="false" %>

© . All rights reserved.