只想知道 发表于 2015-1-16 22:36:12

ASP.NET网页编程之怎样编写高功能的使用程序

我有个同学,他是搞Java的,他给我说“Java不是效率低,而是速度慢。”,我不是搞Java的,我实在想不透这句话的含义,难道执行速度不就是效率低吗?难道执行速度慢还成效率高了?程序|功能  在这个硬件功能一日千里的年月里,我们充实的享用着硬件带给我们的“收费午饭”,似忽软件的效力成绩已不再是一种被开辟者体贴的成绩,可是,跟着CPU的主频进步措施愈来愈慢,高速缓存也不是能够无穷制增添,新手艺的利用渐渐被用来进步硬件的功能,这时候候,要充实发扬这些新特征,软件的撑持就显得很主要了,因而,程序的运转效力再一次映进我们的视野,新时期的软件优化,我们该何往何从?

  瞥见这篇文章的题目,你大概会说:噢,有需要吗,如今的电脑速率愈来愈快,何必往吃力写高功能的程序呢?假如程序功能其实没法奉承,满意不了需求,那年夜不了往换一块更快的CPU,成绩就能够轻松办理了。

  也许已经云云,但各种迹象标明,硬件业为软件业供应的收费“功能提拔”午饭已将近到头了,CPU的主频进步措施愈来愈慢,高速缓存也不是能够无穷制增添,如今CPU更多地用新指令集、并行实行、乱序实行、多处置内核等手艺来进步速率,而这些手艺都必要软件的共同才干发扬感化。假如软件没有利用MMX、3DNow、SSE等指令集,那末就没法享用这些指令集带来的功能提拔;假如程序外部并行性欠好(没有利用多线程构架、实行流中前提转移过量),那末就没法高效使用CPU的并行处置功效(多内核、乱序并行实行)。以是,“怎样编写高功能程序”仍是一门必要细心研究的学问。

  侥幸的是,这些“必要软件的共同”的事情年夜多半能够由编译器来主动完成。以是尽年夜多半情形下我们不必要也不该该就义程序的可读性往做部分优化。本文的“什么时候不该该做优化”一节对此举行了具体会商。

  可是,也有良多优化,出格是较年夜粒度、较高笼统条理的优化,最少在今朝,编译器是没法做到的。好比,把单线程构架改成多线程构架(这点十分主要,不然哪怕运转在四内核的处置器上你的程序也只能占用一个内核,而如今Intel、AMD、IBM都把在处置器上集成多内核看成了次要的提拔处置器功能的手腕),利用较低工夫庞大性的算法,等等。本文的“什么时候应当做优化”和“优化的步骤”两个大节对此做了睁开叙说。

  触及到较高条理的优化,和体系构架对功能的影响,实在有良多纪律可行。本文的“计划构架时要注重的一些准绳”和“功能形式与反形式”两大节对此举行了叙说。

  在开辟中,我们最常常碰到的优化成绩是:内存分派(在年夜多半操纵体系中,从堆上分派内存是开支对照年夜的操纵),线程同步(分歧的同步原语功能差异很年夜),字符串操纵(STL中的string真的要比char*慢吗,Copy-on-Write的string是进步了仍是下降了功能),和这3个成绩的组合(在多线程情况下举行触及到内存分派的字符串操纵)。

  本文也对照细致地切磋了这些罕见的成绩。

  什么时候不该该做优化

  用3句话来归纳综合:假如没无数据证实“功能没有到达目标”,就不要做优化;假如待优化部分不是在关头路径上,就不要做优化;假如没无数据证实“优化的确起感化了”,就不要利用优化的代码。

  这3句话中的“数据”指的次要是用profiler摹拟各类实在大概极限情形下跑出的数据。面前的理念是,要对症下药,工夫花在刀刃上(注重80/20法例),用数听说话,不要想固然。

  好比,若你介入开辟的一个软件,测试时发明启动和加入花的工夫都对照长,在代码复审时也的确发明,启动和加入部分的代码不敷高效。因而,保持休假工夫,终究把这部分优化好了。嗯,且慢,再看一下需求。噢,这个软件会被如许用:启动以后就会24x7地一直机地运转,直到两年后被新版本取代。那末就是说,启动和加入代码只会被实行一次。你保持休假工夫所做的优化值得吗?优化之前请先反省代码是不是在关头路径上。

  再好比,你发明代码中有一些小函数,另有一些轮回体,想优化一下,就把小函数都内联了,把轮回体睁开了。这时候你就必需用数据来证实,你的优化的确起感化了,而没有“好意帮倒忙”地让优化起反感化。你大概会惊奇,“怎样大概”?噢,完整有大概的,由于大概本来的这部分代码对照小,恰好够放在CPU的一级高速缓存中,大概够放在物理内存中。你优化事后代码体积增添了,因而缓存中放不下了,大概乃至内存都放不下要用虚存了,因而CPU大概操纵体系不能不常常换页,功能会年夜幅度下降。以是,不要想固然,要用数据证实你所做的优化的确是优化。

  另有良多“好意没好报”、“优化反被优化误”的例子。好比良多编译器城市主动辨认对数组操纵的for轮回如许的代码形式,并主动做优化。假如你多事地本人往做了优化,改成了指针操纵,编译器大概就不熟悉这个代码形式了,因而就只好守旧地发生非优化的代码。如许发生的代码常常反而效力下降了。

  再好比如今良多JVM城市辨认String操纵的形式。若你为了大概的功能提拔而手工地把对String的操纵改成不那末直不雅文雅的StringBuffer操纵,那不但下降了代码的可读性,还给JVM的优化机制帮了倒忙。

  再好比,Copy-On-Write是一种经常使用的对字符串操纵的优化,能够年夜幅度削减内存分派和读写操纵。可是在多线程情况中,为了坚持Copy-On-Write的准确性,就不能不分外增添很多线程同步操纵。事实是内存操纵的开支年夜仍是线程同步操纵的开支年夜呢?最好用数据来讲话。现实上,在多线程情况中Copy-On-Write多数是个得失相当的优化。之前很多STL完成中string都用了Copy-On-Write,但如今很多多少STL完成都摒弃了这类做法。实在我以为更好的举措是供应参数来让用户选择。究竟假如不必要用到多线程,Copy-On-Write仍是很好的。
  什么时候应当做优化

  假如前一节所说的“不该优化”的条件不建立,那末就只能做优化了。详细的说:假如数据标明,功能的确没有到达目标,出格是当profiler标明,某处关头路径上的代码实行占用了大批的工夫,那末就是优化的时分了。

  起首,要确保你要优化的代码是准确的,没有任何已知bug。由于优化后的代码常常会变得更庞大而难以修正,以是要趁代码还对照复杂的时分赶忙把bug都修失落吧。

  然后,要确认功能目标,能够查specification,大概假如不分明的话再问问客户,大概依据其他功效性需求盘算得出。用profiler搜集今朝的功能数据,和功能目标对照,以断定是不是必要优化、那里必要优化。(数据要保存,由于等优化完后还要用这些数据来做对照,以反省优化是不是无效。)罕见的profiler有RationalQuantify、BorlandOptimizeit等等。良多UNIX上面都自带了profiler,好比prof、gprof等,关于一样平常的利用已够了。

  第三,举行优化。前面“经常使用的优化办法”一节对此举行了具体先容。能够照着列出的罕见的优化办法一个个地套用,大概更好的举措是举行一次团队思想风暴集会,让人人提出各类大概的优化计划。记得优化时不要删除本来的完成。能够在源文件中以替换函数大概正文的体例保存本来的完成。

  第四,利用profiler,考证优化是不是如所想的那样无效。假如无效,那是最好;假如有效乃至是帮了倒忙,那末就赶忙作废修改,利用本来的版本,然后持续实验其他的优化计划。记得优化要一步一步来,从最费事且最无效的计划到最贫苦且收益最小的计划。一旦告竣功能目标就罢手,不要恋战。

  最初,记得对优化过的代码实行单位测试,看看有无为了功能就义了准确性。要记得在正文大概文档中为优化留下纪录。

  经常使用的优化办法

  最复杂的优化:请反省是不是利用了编译器的最新版本,是不是把优化编译开关翻开了,是不是准确指定了方针处置器(以便利用MMX、SSE、3DNow!等高功能指令集和让编译器主动为处置器所撑持的其他初级特征做优化)。假如公布的产物要撑持多种处置器,那末假如大概的话,请独自为每种处置器举行编译,分离公布,大概利用统一个公布包但让安装程序主动检测处置器型号并安装对应的二进制版本,大概把会在关头路径上实行的代码封装成静态链接库,然后让程序启动时主动检测处置器型号并加载为响应型号优化过的静态链接库版本。

  另有,要确保利用了高功能的库,好的算法。好比,一样是从堆上分派内存,分歧编译器供应的malloc大概new的完成,功能差别就不小。GCC利用的DLmalloc就对照高效,Borland的编译器供应的完成利用了相似内存池的体例来静态办理内存,效力也很高,但也有些编译器对此并没有做甚么优化,间接举行体系挪用。不但malloc/new云云,STL的allocator也是云云。SGISTL带的allocator为小于128字节的内存块的分派举行了出格优化(用内存池完成),以是小型字符串和其他会用到allocator此项功效的操纵城市功能对照好,但其他STL完成就没有做如许的优化。

  选择准确的算法,常常比优化地完成算法更主要。由于分歧工夫庞大度的算法大概会给功能带来几个数目级的差别,而完成上的优化则常常支付很年夜、所得甚少。假如偶然候精度不是那末主要,大概不必要找最好的了局只必要找近似最好的了局,那末常常能够用低工夫庞大度的近似算法来取代。

  别的,查表法也是个经常使用的技能。假定,用某个公式能够把黑色图象转换成灰度图像,那末假如转换处置量很年夜的话,对每一个象素都用该公式盘算一边就不划算了,完整能够事前对一切色彩都盘算好,然后处置时查表便可。对三角函数也是云云。固然,为了减小表的尺寸,在精度上常常必要就义一些。

  但也不要觉得由于是事后盘算的不必要思索盘算价值,大概内存对照年夜假造内存更年夜,就能够把表做得很年夜。记着操纵体系大概操纵体系举行内存换页大概Cache换页都是要工夫的,两个临界点分离是Cache的尺寸和物理内存的尺寸。详细是全体盘算,仍是全体查表,仍是部分盘算部分查表,表要做很多年夜,这些都必要实验并用实践数据来撑持。一个对照庞大的做法是静态地把盘算出来的值缓存到希罕表中并供今后利用时查询,表的物理尺寸依据事先呆板的Cache、内存情况静态设置。

  假如利用Java大概.NET上的编程言语的话,由于渣滓会占用空间,渣滓搜集器的实行会占用工夫,以是除优化算法及实在现,还要注重你的代码对渣滓搜集器是不是友爱。好比有无实时把不必的援用置成null,有无不用要的finalizer等等。

  要制止很年夜的轮回体,由于它们常常会超越Cache的尺寸。尽量制止庞大的if-else大概switch-case语句,由于古代CPU的乱序实行功效瞥见这些语句会以为很无法。即使你非要用这些语句,最好养成习气,把最大概的分支放在最后面。另有,假如大概的话,不要在轮回体中利用这些前提分支语句。

  有一些典范著作,如ThePracticeofProgramming(《程序计划理论》)、ProgrammingPearls(《编程珠玑》)、CodeComplete2e(国际今朝只出书了第1版,叫《代码年夜全》)也都提到了良多优化手艺,可是,很主要的一点是,这些书都很少提到大概没有睁开讲“构架计划时注重不要留下功能瓶颈大概缺点”这个成绩。这已超越了优化的范围,而是请求在计划肇端阶段时就思索到功能需求。现实上,在硬件功能极年夜进步、优化编译器年夜行其道的明天,我们写程序时已基础上很少必要往思索部分的微不雅完成是不是优化了,由于有95%的大概编译器会替你往费心,大概基本功能不优化也可满意需求。乃至假如程序的外部布局对照明晰的化,算法也是能够很简单地交换的(好比用Strategy形式,大概Policy-BasedDesign的体例)。但也有的器材不太幸亏程序写完后再改,但又大概对功能有极年夜影响:那就是整体的计划和构架,和一些影响面很广的计划决议/弃取。在明天,这些对照微观的内容远比微不雅的优化技能要主要。

  读者大概要问了:“不是说‘不用要的优化是统统罪行的源泉’、‘没无数据证实就不要做优化’吗?在计划肇端阶段基本还没有代码能够实行,怎样取得数据?你怎样包管这不会是不用要的优化呢?”噢,这个成绩很好回覆:当计划还没构成,代码还没写时,这不叫优化,仅仅是计划。优化是一种改动,把现有的迟缓的器材酿成疾速的器材。而计划时“原本无一物,何来谈优化”呢。

  更况且,一些对照微观的构架上的决议,往后重构起来会十分坚苦,以是一入手下手就应当要思索到。假如一入手下手需求还没有明白而且你也估计不到往后会有如许的功能需求,那末没有思索到也不克不及怪你。但如果一入手下手客户就提出了明白的功能请求,大概你内心很分明客户必定会必要如许的功能,而你计划时却仍然选择了没法大概难以满意如许功能请求的构架,那末这就不太好了。别的,假如两种计划/构架,并没有明白的完成庞大性大概文雅水平的不同,而个中一种计划/构架分明功能扩大性更好,那末也应当选择后一种。这不叫“prematureoptimization”,而叫做“制止prematurepessimization”(见C++CodingStandards一书的Item9)。

  别的,另有一些很罕见的和功能相干的话题。并且很多人对它们的熟悉另有一些误区,好比资本(出格是内存)的猎取和开释、线程间的同步(也可看做特别资本――各类线程锁的猎取和开释)、字符串(大概其他缓冲区)的处置,和这些操纵的组合。这些话题很值得进一步会商,在从此的文章中,会再和读者举行更深条理的交换。
你觉得学习.NET怎么样,我懂的少,问的可能很幼稚,见笑了啊:)

乐观 发表于 2015-1-19 18:06:43

同时也感谢博客园给我们这个平台,也感谢博客园的编辑们做成专题引来这么多高人指点。

莫相离 发表于 2015-1-27 07:46:03

代码逻辑混乱,难于管理:由于ASP是脚本语言混合html编程,所以你很难看清代码的逻辑关系,并且随着程序的复杂性增加,使得代码的管理十分困难,甚至超出一个程序员所能达到的管理能力,从而造成出错或这样那样的问题。

海妖 发表于 2015-2-5 04:15:10

逐步缩小出错代码段的范围,最终确定错误代码的位置。

透明 发表于 2015-2-11 04:19:17

提供基于组件、事件驱动的可编程网络表单,大大简化了编程。还可以用ASP.NET建立网络服务。

不帅 发表于 2015-3-1 21:36:43

但是目前在CGI中使用的最为广泛的是Perl语言。所以,狭义上所指的CGI程序一般都是指Perl程序,一般CGI程序的后缀都是.pl或者.cgi。

小妖女 发表于 2015-3-11 00:06:17

同时也感谢博客园给我们这个平台,也感谢博客园的编辑们做成专题引来这么多高人指点。

小魔女 发表于 2015-3-17 16:21:07

ASP.NET:ASP.net是Microsoft.net的一部分,作为战略产品,不仅仅是ActiveServerPage(ASP)的下一个版本;它还提供了一个统一的Web开发模型,其中包括开发人员生成企业级Web应用程序所需的各种服务。ASP.NET的语法在很大程度上与ASP兼容,同时它还提供一种新的编程模型和结构,可生成伸缩性和稳定性更好的应用程序,并提供更好的安全保护。

精灵巫婆 发表于 2015-3-24 12:28:44

如今主流的Web服务器软件主要由IIS或Apache组成。IIS支持ASP且只能运行在Windows平台下,Apache支持PHP,CGI,JSP且可运行于多种平台,虽然Apache是世界使用排名第一的Web服务器平台。
页: [1]
查看完整版本: ASP.NET网页编程之怎样编写高功能的使用程序