如何用c#开发高性能的软件

 我来答
Tech_Monkeye5
2017-11-17 · TA获得超过983个赞
知道小有建树答主
回答量:330
采纳率:92%
帮助的人:66.9万
展开全部

这个涉及到两个方面:

用C#开发高性能的软件这个问题纵向比较的话,其实C#并不占优势,它毕竟是第五代语言,使用的是类库,大量引用反射,尤其其中间语言的特性(移植性),它本身的性能上来说是有很大的损失的,当然你可以理解C#是拿性能换取了代码的可读性、易用性及移植性等特点。所以对比C/CPP来说,C#本身是没有任何性能上的优势的,所以如果说起语言性能,只拿来比较PHP/JAVA而已,并不能真正地做到性能上的很大优势。这也是驱动/单片/显卡/实时系统等各方面的应用薄弱。这也是C#的定位在于应用软件行业,而不是驱动/单片/实时系统等行业的原因之一。所以高性能软件如果是纵向比较,还是回归到C/CPP,当然由于汇编开发与维护的难度较高,这个语言只在C/CPP中局部开发使用(做为提高性能的胶水使用)。

如果只在C#范围内来说,不同的人程序员存在不同的开发习惯,各程序员的各模块性能也有高有低,这种情况下的实现相同功能的应用软件在性能上也存在着高低之分。

针对C#来说,其实我不建议过份追求性能,因为C#本身并不是高性能开发语言——但并不是说你可以随心所欲地不管性能(很多程序员就是这样,你说他的性能低,他就反驳说C#也不是什么高性能语言,要追求性能用汇编去),其实这种思想是要不得的——他们为什么不想想同样的功能,为什么有人用同样的C#语言却比他高几个数量级?我曾用用2个半小时处理去16G的交互数据,但也我见过有人用两天的时间去处理14G的几乎同样的数据——这就是C#内部的性能问题。

其实如果开发高性能软件并拘限于C#语言的话,那么有很多东西是要注意的:

  1. 多线性或TPL ——我的意思是说如果处理一些简单的重复性的任务时,不妨考虑使用多线程或任务并行库进行开发,它没有提升性能,但却缩短了软件工作时间。当然还要考虑到阻塞等各种情况,如果不会用,有人会适得其反。事件或委托也是多线程的一种,所以有时使用事务驱动开发软件也不失为一种提高软件可用性的一种方式。所以如果一个程序员连委托或事件都没有写过——他说他了解多线程了,其实只是皮毛,多线程远没有其看到的那么简单。

  2. 领域知识扩充——这个其实是诸多程序员易犯的毛病,很多人都讲算法,其实这个也算是算法中的一点内容,举个不恰当的例子,明明C#中存在Math.Power(5,5)可以实现5的五次方,你还用着循环来让5乘5,能说性能高吗?我知道这个例子太浅显,很多程序员不愿意承认——其实是他们根本认识不到,如果是一个小学生的程序员其实是还没有接触到乘方概念的——这个问题我扩大一下,程序员还没有理解整个所处的业务行业,所以这个例子并不是说你对C#语言或.net类库不了解——而是说你目标软件的行业中还存在有你未知的知识范畴。而这些要和行业内的工作人员进行多多沟通才能了解到这个行业的更多知识——这也是为什么很多行业在招聘时会要求在同类行业工作过的经历。

  3. 语言层面的规范——软件开发的整个过程中,很多时间可能是由于我们开发周期等相关的限制,成为我们不去追求性能的借口之一。开发周期短的借口能说勉强说得过去(有时确实如此),但投入成本少的借口就不伦不类了。语言层面上除了对基本的开发习惯进行规范外部分时候还需要对性能要求上进行一定的规范,比如表连接时应该使用小表连接大表,避免使用消耗性能的语句,如多次字符串连接时应该改为StringBuilder而不是String进行拼接,数据库获得数据时应使用DataReader而不是DataAdapter等等。

  4. 小内存和CPU占用——这一点很多人都不明白,为什么使用较少的内存或CPU占用反倒是提高了性能呢?其实这个是对模块来说的,如果每个模块都占用大量的内存与CPU,那么软件最终的整合会造成内存上的抖动和CPU轮片的等待。也就是说基本上从软件运行的角度考虑了整个软件运行过程中的资源分配问题——当然这是一种策略而已,不见得是最优的,但如果没有控制则会出现大量的问题,我说这个很多人不会同意——但其实你是该知道,为什么那么多的程序员都喜欢升级CPU、添加更大内存就说明了一点问题,有资源就不能省点用?但凡是不以为然的程序员其实并没有对自己程序进行控制。

  5. 巧妙的例外——我们都知道在,软件不可能在运行一点错也不犯,如果一犯错就摞给你崩溃看看,这样的话谈什么性能?而增加程序的鲁棒性就涉及到程序代码的增加,这涉及到性能的问题。但这里我要说的是我们应用有统一的例外机制处理办法,而不是随意在代码中抛出例外。就算你每个模块或细节到每个成员方法都加上try,也不见得组装后的程序不会犯错,所以我们一般情况下在核心层是允许抛出例外的,所以如果谁在核心层大量使用try结构,那么这个核心层的性能已经不高了,为什么我们不把例外冒泡到最后层(场景层/调用层)进行统一处理呢?所以但见到try结构直接或间接嵌套的,这些程序员根本不懂性能,也不懂C#的例外机制,更甚者,我见过在try结构的catch分支中再thorw出一个例外来——如无特殊需求,这类程序员基本上是脑子进水了(一般情况下,catch到例外时性能会下降,所谓的处理后再抛出一个例外,那么外层的try结构会再次引出性能下降,例外是可以冒泡到外层的,如果不是因为安全或其他特殊原因,这么做纯粹是拉低性能的做法,这也是为什么核心层允许例外而很少使用try结构的原因)!所以对于整体程序来说,良好的设计能做我们提整体的性能的。

  6. 良好的基础知识与习惯——这个多数还是要求程序员类的线程安全和性能上有些掌握的。之所以独自列出来,是因为太多在存在这方便的不好的习惯了。比如说类与结构体的区别,如果要大量使用的结构,且数据量小的情况下,应当使用结构体,不要动不动用类。结构体是值类型,存储在栈上,性能各方便也比类的性能好点,但对于较大的数量时会占用较大的栈空间,对整体软件不利,所以该用结构体的时候不要去用类,该用类的时候不要去用结构体——多少程序员还没有使用结构体?微软的建议是如果内存空间小于16K建立考虑使用结构体(这个只是建议,我觉得这个数字已经很大了)。还有多少个程序员为了方便大量使用静态类?其实在核心时我们可以巧灵构造静态类,在外围编程中应慎用,它不旦破坏面向对象的内聚性,还会导致你的内存占用增长,每个人都有这习惯的话,性能肯定高不到哪儿去!两类的坏习惯都没有?那你一定有第三种——设计对象或类是大量使用的是可读内容而没有设计,什么意思呢?比如你给类一个ID,明明是一个数字,却习惯地使用了string——还美其名称“可读性差”,最常见的就是程序之间的数据交互,其实设计成二进制交互内容就可以了,偏要转换一下转变成string,使用时再转换回来等等,如果你是方便你自己的“可读性”,那么就别提性能问题,计算机使用二进制方便还是使用在你理解意义上的可读文字方便?这种情况我经常见到——程序员为了抽样数据方便,经常两机器之间传递的是文本而不是二进制的data文件,事实上为了性能我们使用的是人不可读的二进制文件,如果你真要读这个文件,你可以开发个软件或工具来读嘛,干嘛了为你能读一点东西让计算机绕这么大的圈呢?我兴趣个例子,数据库设计的编码字段是存在 varchar(16)存一个十六进制的字符串好呢,还是直接设计成bigint好呢?所以写代码时多以二进制进行处理,而不要让程序迁就你个人,这样会提高你程序性能的。

基本上来说,高性能就处理这么多情况下的考虑,至于细节,这里边是非常多的内容需要注意的。说句不好听的,我们按计算机运行方式设计出的程序当然要比按你的方式要快的多。所以一些老程序员甚至我们在数值云计算时,如x要乘以16时,就会写上x <<=4来代替x *= 16;所以真想高性能,这里边涉及的细节还是非常多的,

zjhpurpose
2018-05-27 · TA获得超过793个赞
知道答主
回答量:232
采纳率:0%
帮助的人:9.9万
展开全部
你是不是对C#充满了很大的期望呀。。。你就错了。注意一点,凡是微软的东西只是一个方便 性罢了。。好玩罢了。。干工作的软件微软是不行的。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式