提高ASP.NET应用性能的十大方法

一、返回多个数据集

         检查你的访问数据库代码,看是否存在着要返回多次的请求。每次往返降低了你的应用程序的每秒能够响应请求的次数。通过在单个数据库请求中返回多个结果集,可以减少与数据库的通信时间,使你的系统具有扩展性,也可以减少数据库服务器响应请求的工作量。

         如果你是用动态的SQL语句来返回多个数据集,那我建议你用存储过程来替代动态的SQL语句。是否把业务逻辑写到存储过程中,这个有点争议,但是我认为,把业务逻辑写到存储过程里面可以限制返回结果集的大小,减少网络数据的流量,在逻辑层也不用再过滤数据,这是一个好事情。

         用SqlCommand对象的ExecuteReader方法返回一个强类型的业务对象,再调用NextResult方法来移动数据集指针来定位数据集。示例一演示了一个返回多个ArrayList强类型对象的例子。只从数据库中返回你需要的数据可以大大的减少你的服务器所耗用的内存。


二、对数据进行分页

       ASP.NET的DataGrid有一个非常有用的功能:分页。如果DataGrid允许分页,在某一时刻它只下载某一页的数据,另外,它有一个数据分页的齐览导航栏,它让你可以选择浏览某一页,而且每次只下载一页的数据。

       但是它有一个小小的缺点,就是你必须把所有的数据都绑定到DataGrid中。也就是说,你的数据层必须返回所有的数据,然后DataGrid再根据当前页过滤出当前页所需要的数据显示出来。如果有一个一万条记录的结果集要用DataGrid进行分页,假设DataGrid每页只显示25条数据,那就意味着每次请求都有9975条数据都是要丢弃的。每次请求都要返回这么大的数据集,对应用程序的性能影响是非常大的。

      一个好的解决方案就是写一个分页的存储过程,例子2是一个用于对Northwind数据库orders表的分页存储过程。你只需要传当前页码,每页显示的条数两个参数进来,存储过程会返回相应的结果。

      在服务器端,我专门写了一个分页的控件来处理数据的分页,在这里,我用了第一个方法,在一个存储过程里面返回了两个结果集:数据记录总数和要求的结果集。

      返回的记录总数取决于要执行查询,例如,一个where条件可以限制返回结果集的大小。因为在分页界面中必须要根据数据集的大小来计算总的页数,所以必须返回结果集的记录数。例如,如果一共有1000000条记录,如果用where条件就可以过滤成只返回1000条记录,存储过程的分页逻辑应该知道返回那些需要显示的数据。


三、连接池

        用TCP来连接你的应用程序与数据库是一件很昂贵的事情(很费时的事情),微软的开发者可以通过用连接池来反复使用数据库的连接。比起每次请求都用TCP来连一次数据库,连接池只有在不存在有效的连接时才新建一个TCP连接。当关闭一个连接的时候,它会被放到池中,它仍然会保持与数据库的连接,这样就可以减少与数据库的TCP连接次数。

        当然,你要注意那些忘记关的连接,你应在每次用完连接后马上关闭它。我要强调的是:无论什么人说.net framework中的GC(垃圾收集器)总会在你用完链接对象后调用连接对象的Close或者Dispose方法显式的关闭你的连接。不要期望CLR会在你想象的时间内关掉连接,虽然CLR最终都要销毁对象和关闭连接,但是我们并不能确定它到底会在什么时候做这些事情。

      要用连接池优化,有两条规则,第一,打开连接,处理数据,然后关闭连接,如果你必须在每次请求中多次打开或关闭连接,这好过一直打开一个连接,然后把它传到各个方法中。第二,用相同的连接字符串,如你用基于登录用户的连接字符串,这将不能利用连接池的优化功能。如果你用的是集成的论证,因为用户很多,所以你也不能充分利用连接池的优化功能。.net CLR 提供了一个数据性能,它在我们需要跟踪程序性能特性的时候非常有用,当然也包括连接池的跟踪了。

      无论你的应用程序什么时候要连在另一台机子的资源,如数据库,你都应该重点优化你连资源所花的时间,接收和发送数据的时间,以及往返回之间的次数,优化你的应用程序中的每一个处理点(process hop),它是提高你的应用性能的出发点。

      应用程序层包含与数据层连接,传送数据到相应的类的实例以及业务处理的逻辑,如授权,更重要的,这里要完成缓存逻辑。


四、ASP.NET缓存API

        在写应用程序之前,你要做的第一件事是让应用程序最大化的利用ASP.Net的缓存功能。

        如果你的组件是要在Asp.Net应用程序中运行,你只要把System.Web.dll引用到你的项目中就可以了。然后用HttpRuntime.Cache属性就可以访问Cache了。(也可以通过Page.Cache或者HttpContext.Cache访问)

       有以下几条缓存数据的规则,第一,数据可能会频繁的被使用,这种数据可以缓存,第二,数据的访问频率非常高,或者一个数据的访问频率不高,但是它的生存周期很长,这样的数据最好也缓存起来。第三是一个常常被忽略的问题,有时候我们缓存了太多数据,通常在一台X86的机子上,如果你要缓存的数据超过800M的话,就会出现内存溢出的错误。所以说缓存是有限的。换句话说,你应该估计缓存集的大小,把缓存集的大小限制在10以内,否则它可能会出问题,在Asp.net中,如果缓存过大的话也会报内存溢出错误,特别是如果缓存大的DataSet对象的时候。

        这里有几个你必须了解的重要的缓存机制,首先是缓存实现了“最近使用”原则,当缓存少的时候,它会自动的强制清除那些无用的缓存,其次“条件依赖”强制清除原则。条件可以是时间,关键字和文件,以时间作为条件是最常用的。在asp.net 2.0中增加一更强的条件,就是数据库条件,当数据库中的数据发生变化时,就会强制清除缓存。


     五、预请求缓存

      在前面,我提到过即使我们只对某些地方作了一个小小的性能改进也可以获得大的性能提升,我非常喜欢用预请求缓存来提升程序的性能。

      虽然Cache API 设计成用来保存某段时间的数据,而预请求缓存只是保存某个时期的某个请求的内容。如果某个请求的访问频率高,而且这个请求只需要提取,应用,修改或者更新数据一次,那么就可以预缓存该请求。

         在CS的论坛应用程序中,每一个页面的服务器控件都要求得到用于决定它的皮肤的自定义的数据,以决定用哪个样式表及其它的一些个性化东西,这里面的某些数据可能要长时间的保存,有些时间则不然,如控件的skin数据,它只需要应用一次,而后就可以一直使用。

        要实现预请求缓存,用ASp.net的HttpContext类,HttpContext类的实例在每一个请求中创建,在请求期间的任何地方都可以通过HttpContext.Current属性访问。HttpContext类有一个Items集合属性,在请求期间所有的对象和数据都被添加到这个集合中缓存起来。和你用Cache缓存访问频率高数据一样,你可以用HttpContext.Items缓存那些每个请求都要用到的基础数据。它背后的逻辑很简单:我们向HttpContext.Items中添加一个数据,然后再从它里面读出数据。

        六、后台处理

           通过上面的方法你的应用程序应该运行得很快了,是不是?但是在某些时候,程序中的一次请求可能要执行一个非常耗时的任务,如发送邮件或者检查提交数据的正确性等。

         当我们把asp.net Forums 1.0集成在CS中的时候,发现提交一个新的帖子的时候会非常慢,每次新增一个帖子的时候,应用程序首先要检查这个帖子是不是重复提的,然后用“badword”过滤器来过滤,检查图片附加码,做帖子的索引,把她添加到合适的队列中,验证它的附件。最后,发邮件到它的订阅者邮件箱中,显然,这个工作量很大。

         结果它把大量的时间都花在做索引和发送邮件中了,做帖子索引是一项很耗时的操作,而发送邮件给订阅者都需要连接到SMTP服务,然后每一个订阅者都发一封邮件,随着订阅用户的增加,发送邮件的时间会更长。

       索引和发邮件并不需要在每次请求时触发,理想状态下,我们想要批量的处理这些操作,每次只发25封邮件或者每隔五分钟把所有的要发的新邮件发一次。我们决定使用与数据库原型缓存一样的代码,但是失败了,所以又不得不回到VS.Net 2005.

        我们在System.Treading命空间下找到了Timer类,这个类非常有用,但却很少有人知道,Web开发人员则更少有人知道了。一旦他建立了该类的实例,每隔一个指定的时间,Time类就会从线程池中的一个线程中调用指定的回调函数。这意味着你的asp.net应用程序可以在没有请求的时候也可以运行这就是后以处理的解决方案,你可以让做索引和发邮件工作在后台运行,而不是每次请求的时候必须执行。

       后台运行的技术有两个问题,第一是,当你的应用程序域卸载后,Timer类实例就会停止运行了。也就是不会调回回调方法了。另外,因为CLR的每个进程中都有许多的线程在运行,你将很难让Timer获得一个线程来执行它,或者能执行它。但会延时,Asp.net层要尽量少的使用这种技术,以减少进程中线程的数量,或者只让请求用小部分的线程,当然如果你有大量的异步工作的话,那就只能用它了。


    七、页面输出缓存和代理服务

      Asp.net是你的界面层,它包含页面,用户控件,服务器控件(HttpHandlers和HttpModules)以及它们生成的内容,如果你有一个Asp.net页面用来输出Html,xml,image或者是其他的数据,对每一个请求你都用代码来生成相同的输出内容,你就很有必要考虑用页面输出缓存了。

      你只要简单的把下面的这一行代码复制到你的页面就可以实现了:<%@ PageOutputCache VaryByParams="none" Duration="60" %> 你就可以有效的利用第一次请求里生成的页面输出缓存内容,60s后重新生成一道页面内容。这种技术其实也是运用一些低层的Cache API来实现。用页面输出缓存有几个参数可以配置,如上面所说的VaryByParams参数,该参数表示什么时候触发重输出条件,也可以指定在Http Get或Http Post请求模式下缓存输出。例如当我们设置该参数为VaryByParams=“Report”的时候,default.aspx? Report=1或者default.aspx?Report=2请求的输出都会被缓存起来。参数的值可以是多个用分号隔开参数。

        许多人都没有意识到当用页面输出缓存的时候,asp.net也会生成http头集(Http header)保存在下游的缓存服务器中,这些信息可以用于Microsoft Internet安全性中以及加速服务器的响应速度。当Http缓存的头被重置时,请求的内容会被缓在网络资源中,当客户端再次请求该内容时,就不会再从源服务器上获得内容了,而直接从缓存中获得内容。

    虽然页面输出缓存不提高你的应用程序性能,但是它能减少了从服务器中加载已缓存页面内容的次数。当然,这仅限于缓存匿名用户可以访问的页面。因为一旦页面被缓存后,就不能再执行授权操作了。


   八、用IIS6.0的Kernel Caching

    如果你的应用程序没有运行在IIS6.0中,那么你就失去了一些很好的提高应用程序性能的方法。在第七个方法中,我讲了用页面输出缓存提高程序的性能的方法。在IIS5.0中,当一个请求来到IIS后,IIS会把它转给ASp.net ,当应用了页面输出缓存时,Asp.net中的HttpHandler会接到该请求,HttpHandler从缓存中把内容取出来并返回。

        如果你用的是IIS6.0.它有一个非常好的功能就是Kernel Caching,而且你不必修改asp.net程序中任何代码,当asp.net借到一个已缓存的请求,IIS的

深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值