<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_看缘工作室</title><subtitle type="text">专注于.Net平台研究与企业信息化项目建设</subtitle><id>http://feed.cnblogs.com/blog/u/50701/rss</id><updated>2012-01-25T04:37:49Z</updated><author><name>Aicken(李鸣)</name><uri>http://www.cnblogs.com/isline/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/isline/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/50701/rss"/><entry><id>http://www.cnblogs.com/isline/archive/2011/06/28/2091903.html</id><title type="text">有多少爱可以重来 --Visual Studio 2010 的9项改进建议</title><summary type="text">距Visual Studio 2010发布一年多了，这一年多的时间不知“耀”他们过得如何，是已经分开还是依然在一起？是否还记得当年发布会上，女孩突然出现时给他的惊喜?不过还好，相信大家都有自己的成长与进步，这就是Coding Life，我们都在得失中老去。。。</summary><published>2011-06-28T01:37:00Z</published><updated>2011-06-28T01:37:00Z</updated><author><name>Aicken(李鸣)</name><uri>http://www.cnblogs.com/isline/</uri></author><link rel="alternate" href="http://www.cnblogs.com/isline/archive/2011/06/28/2091903.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/isline/archive/2011/06/28/2091903.html"/><content type="html">&lt;p align="center"&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/isline/201106/201106280937169912.png"&gt;&lt;span size="3" style="font-size: small;"&gt;&lt;img height="310" width="412" src="http://images.cnblogs.com/cnblogs_com/isline/201106/201106280937188126.png" alt="image" border="0" title="image" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 距Visual Studio 2010发布一年多了，这一年多的时间不知&amp;ldquo;耀&amp;rdquo;他们过得如何，是已经分开还是依然在一起？是否还记得当年发布会上，女孩突然出现时给他的惊喜?不过还好，相信大家都有自己的成长与进步，这就是Coding Life，我们都在得失中老去。。。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 话入正题，本人从2002年接触DotNet至今，历经Visual Studio 的代代更新，看到它的成长，我很欣慰~~&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Visual Studio是我用过最满意的代码编辑器，但还是有一些个人觉得需要改进的地方，这里写出来，大家补充，也许有的功能已经实现，还请各位大方指出。希望我们的Visual Studio越来越好，同时也希望MS早日推出跨OS平台的DotNet FrameWork。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1. 快速定位文件路径&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在右键点击文件&amp;agrave;属性后，属性对话框会显示出该文件的&amp;ldquo;完整路径&amp;rdquo;信息，如果&lt;/span&gt;&lt;span size="3" style="font-size: small;"&gt;这时需要定位至该文件所处的文件夹(比如完成一些拷贝粘贴工作)，则还要复制路径，然后在Explorer中打开。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 建议：在&amp;ldquo;完整路径&amp;rdquo;右侧边缘处提供一个按钮，点击按钮后直接打开该文件所在文件夹窗口。&lt;/span&gt; &lt;/p&gt;&lt;p align="center"&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/isline/201106/201106280937184604.png"&gt;&lt;span size="3" style="font-size: small;"&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/isline/201106/20110628093719733.png"&gt;&lt;img height="131" width="367" src="http://images.cnblogs.com/cnblogs_com/isline/201106/201106280937197734.png" alt="image" border="0" title="image" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/a&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2. 代码书签&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 分布于不同文件的代码是有逻辑关系的，经常会有类似情况：检查一段代码的时，需要同时关注其他几段相关代码，这些代码有可能在一个文件中，也有可能在不同文件中，甚至使用2个屏幕核对相关代码，这样如果使用滚动条+行号的形式，在这些代码段中定位了，未免有些郁闷。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 建议：提供类似断点的标注方式，但只是标注，目的是让程序人员可以快速的给代码段打上标记，以在不同屏幕、文件切换过程中方便的分辨。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3. Profile导入与导出&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 很多VS用户并不喜欢白底黑字的界面，更多的人出于对眼睛的保护，喜欢把背景&lt;/span&gt;&lt;span size="3" style="font-size: small;"&gt;色、字体等设置成别的格式，可是重新安装OS后就不得不把以上工作重新做一遍，浪费时间啊！&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 建议MS提供一个功能，该功能可以导入导出所有&amp;ldquo;选项&amp;rdquo;菜单中自定义的Profile。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;如果可能，MS还可以根据不同国家的人，不同角色的人(例如程序员与架构师、测试员)，提供不同的内置偏好，以供相应人群使用。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4. 关于静态变量&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 静态可是个好东西啊！可是就是不受DotNet垃圾回收器的待见，用完后如果不置&lt;/span&gt;&lt;span size="3" style="font-size: small;"&gt;null，他就会一直呆在你那个AppDomain，GC不会去管他，因为它就是一个树图的根！&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 试想一下如果一个程序中大量使用静态委托，而又没有适当的置null，是不是会导致频繁的溢出呢？&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 建议：编译过程中，对于静态变量的使用，可以根据引用其的类的时序图，判断是否有漏置null的情况，如果质疑，则提出warning级别的提示。当然这只是给编程人员提个醒，起到辅助的作用，真正的代码安全还得靠经验。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5. 提供灵活的垃圾回收&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 我想这一点并不是所有人都需要的。因为垃圾收集工作悄然无声的进行，有些时候&lt;/span&gt;&lt;span size="3" style="font-size: small;"&gt;我并不希望GC启动，而有些时候我只希望做垃圾标记，而不希望GC压缩环节的启动，(因为在不久，也许会有更大规模的内存移动)。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 建议：能否提供一个类似于Lock的方法，其中的代码执行过程中GC不要启动呢？&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 6. 项目顺序&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 如果一个解决方案中有多个项目，你怎样手动排列它们在&amp;ldquo;解决方案管理器&amp;rdquo;中的显示顺序呢？靠在项目名字前面加入数字序号吗？&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 建议：增加手动排序功能。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 7. 查找替换目录&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在&amp;ldquo;查找与替换&amp;rdquo;菜单中，查找范围只有如下几项：&lt;/span&gt; &lt;/p&gt;&lt;p align="center"&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/isline/201106/201106280937241261.png"&gt;&lt;img height="121" width="258" src="http://images.cnblogs.com/cnblogs_com/isline/201106/201106280937244675.png" alt="image" border="0" title="image" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 如果想替换某个文件夹下所有或者某种扩展名的文件中的关键字，就不好弄了。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 建议：增加类似DW那种在文件夹范围内操作的选项。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8. 加快ASP. NET Design界面与解决方案加载的速度&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 有过ASP.NET开发经验的人都有此体会，当你从Code界面切换至Design界面时，&lt;/span&gt;&lt;span size="3" style="font-size: small;"&gt;这个操作会损耗很长的时间，甚至会使人不耐烦。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 而解决方案的加载也是如此，如果一个解决方案中项目过多(几十个)，加载时间会消耗很多，令人难以理解。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 建议：加快速度。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 9. 接口定义的变量，F12时定位至&amp;ldquo;实现&amp;rdquo;而不是&amp;ldquo;接口&amp;rdquo;&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 例如有如下代码：&lt;/span&gt; &lt;/p&gt;&lt;p&gt;IDataTableContainer dtc = new OracleContainer(); &lt;/p&gt;&lt;p&gt;dtc.TransactionBegin(ref cd); &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IDataTableContainer是一个接口，里面有一个方法签名TransactionBegin。当你将光标置于dtc.TransactionBegin(ref cd)上，并使用F12查找定义时，VS定位的是接口的位置，而不是接口的实现，可是有些时候我们希望找到的是具体方法，而不是签名。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 建议：上述现象可使用F12定位至接口的实现。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&amp;nbsp; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 以上建议功能可能已经有插件实现，欢迎共享！&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/isline/aggbug/2091903.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/isline/archive/2011/06/28/2091903.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/isline/archive/2011/06/27/2091079.html</id><title type="text">DotNet并行计算使用误区(三)</title><summary type="text">这篇文章主要是从实用的角度讲解并行计算需要了解的一些基础知识以及需要注意的地方，包括并行循环的方法、如何终止、线程安全、常用类型等几方面。</summary><published>2011-06-27T01:17:00Z</published><updated>2011-06-27T01:17:00Z</updated><author><name>Aicken(李鸣)</name><uri>http://www.cnblogs.com/isline/</uri></author><link rel="alternate" href="http://www.cnblogs.com/isline/archive/2011/06/27/2091079.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/isline/archive/2011/06/27/2091079.html"/><content type="html">&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 这篇文章主要是从实用的角度讲解并行计算需要了解的一些基础知识以及需要注意的地方，包括并行循环的方法、如何终止、线程安全、常用类型等几方面。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;关于TPL中提供的并行方法，这里就不再多说了，网上有很多例子，本系列文章第三个Topic主要讲的不是&amp;ldquo;如何跑&amp;rdquo;，而是要讲一下&amp;ldquo;如何停&amp;rdquo;。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 曾经查过很多关于二者的资料，可能是我理解的原因，总觉得很少有对其解释正确的，所以我觉得还是有必要写出我的观点，请大家指正。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;Section 1.并行循环的终止：Break与Stop&lt;/strong&gt;&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 关于二者网上有很多解释，很多人都认为，在并行计算中：&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1．Break的调用会导致当前任务和已分配任务的终止&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2．Stop的调用会导致当前任务的终止&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 本人对以上两点持怀疑态度，经过试验证明，Break和Stop并不像以上说的那样。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 这里先解释一下名词，&amp;ldquo;当前任务&amp;rdquo;指的是当前已经触发Break(Stop)条件的那个任务；&amp;ldquo;已分配任务&amp;rdquo;指的是与&amp;ldquo;当前任务&amp;rdquo;并行执行的任务；&amp;ldquo;未分配任务&amp;rdquo;指尚未开始的循环部分。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 有以下测试代码，这些代码在不同核数量的机器上返回的记录数是不同的，这一点待会再说，先看代码：&lt;/span&gt; &lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; Program &lt;br /&gt;&lt;br /&gt;{ &lt;br /&gt;&lt;br /&gt;  &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; List&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Data &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; List&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(); &lt;br /&gt;&lt;br /&gt;  &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; ParallelOptions opt &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; ParallelOptions(); &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Main(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] args) &lt;br /&gt;&lt;br /&gt;{ &lt;br /&gt;&lt;br /&gt;  opt.MaxDegreeOfParallelism &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; Environment.ProcessorCount; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;10&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;br /&gt;&lt;br /&gt;  { &lt;br /&gt;&lt;br /&gt;    Data.Add(i); &lt;br /&gt;&lt;br /&gt;  } &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  Console.WriteLine(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;CPU Degree:&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; opt.MaxDegreeOfParallelism); &lt;br /&gt;&lt;br /&gt;  Console.WriteLine(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;GeneralFor Result:&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;); &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Program().GeneralFor(); &lt;br /&gt;&lt;br /&gt;  Console.WriteLine(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;ParallerStop Result:&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;); &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Program().ParallerStop(); &lt;br /&gt; &lt;br /&gt;  Console.WriteLine(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;ParallelBreak Result:&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;); &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Program().ParallelBreak(); &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  Console.Read(); &lt;br /&gt;&lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;一个普通的For循环 &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; GeneralFor() &lt;br /&gt;&lt;br /&gt;{ &lt;br /&gt;&lt;br /&gt;  &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Data.Count; i&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;br /&gt;&lt;br /&gt;  { &lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (Data[i] &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;5&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    Console.WriteLine(Data[i]); &lt;br /&gt;&lt;br /&gt;  } &lt;br /&gt;&lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;并行计算的Stop &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; ParallerStop() &lt;br /&gt;&lt;br /&gt;{ &lt;br /&gt;&lt;br /&gt;  Parallel.For(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;, Data.Count,opt, (i, LoopState) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;  { &lt;br /&gt;&lt;br /&gt;  &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (Data[i] &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;5&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;br /&gt;&lt;br /&gt;  LoopState.Stop(); &lt;br /&gt;&lt;br /&gt;  Thread.Sleep(&lt;/span&gt;&lt;span style="color: #800080;"&gt;10&lt;/span&gt;&lt;span style="color: #000000;"&gt;); &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  Console.WriteLine(Data[i]); &lt;br /&gt;&lt;br /&gt;  }); &lt;br /&gt;&lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;并行计算的Break &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; ParallelBreak() &lt;br /&gt;&lt;br /&gt;{ &lt;br /&gt;&lt;br /&gt;  Parallel.For(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;, Data.Count, opt, (i, LoopState) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;  { &lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (Data[i] &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;5&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;br /&gt;&lt;br /&gt;    LoopState.Break(); &lt;br /&gt;&lt;br /&gt;    Thread.Sleep(&lt;/span&gt;&lt;span style="color: #800080;"&gt;10&lt;/span&gt;&lt;span style="color: #000000;"&gt;); &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    Console.WriteLine(Data[i]); &lt;br /&gt;&lt;br /&gt;  }); &lt;br /&gt;&lt;br /&gt; } &lt;br /&gt;&lt;br /&gt;} &lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;b&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 下图分别是程序在2(32#)、4(64#)、48(64#)核CPU下运行的结果：&lt;/span&gt; &lt;/p&gt;&lt;p align="center"&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/isline/201106/201106270916132849.png"&gt;&lt;span size="3" style="font-size: small;"&gt;&lt;img height="353" width="603" src="http://images.cnblogs.com/cnblogs_com/isline/201106/201106270916159210.png" alt="image" border="0" title="image" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p align="center"&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 个人认为，不同CPU核数量对于使用Break与Stop终止循环形式的最终记录返回数量是有影响的，即这会影响TPL分配任务的方针，TPL在运行时才会&amp;ldquo;源源不断&amp;rdquo;的分配任务，开启的线程数也是递增形式的。(最大线程数应该有限制，具体是多少不确定，有的说是64也有的说是256，等待高人解答)&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 所以，对于Stop与Break，我的观点是，在并行任意任务中调用Stop方法，则会终止除当前任务外的所有并行任务(包括未分配的和已分配的)，返回最终结果，而不是像传说的那样，终止了当前任务；Break只会停止继续分配新任务，并不影响当前任务的和已经分配的并行任务的执行，而且同样不会终止当前任务。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Stop更改ParallelLoopState 对象的 IsStop值为true；&lt;/span&gt; &lt;/p&gt;&lt;div&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Break更改ParallelLoopState 对象的 LowestBreakIteration 属性值等于 true 。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/div&gt;&lt;div align="center"&gt;&lt;table align="center" cellpadding="0" cellspacing="0" border="1" style="color: #000000;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="142" valign="top"&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/td&gt;&lt;td width="120" valign="top"&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;未分配的任务(未开始的任务)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td width="164" valign="top"&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;已分配的任务(并行中的任务)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td width="142" valign="top"&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;当前任务(触发条件的那个任务)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="142" valign="top"&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;单行中的Break&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td width="120" valign="top"&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;停止分配&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td width="164" valign="top"&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;停止执行(相当于&amp;ldquo;当前任务&amp;rdquo;)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td width="142" valign="top"&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;停止执行&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="142" valign="top"&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;Break&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td width="120" valign="top"&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;停止分配&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td width="164" valign="top"&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;继续执行&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td width="142" valign="top"&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;继续执行&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="142" valign="top"&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;Stop&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td width="120" valign="top"&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;停止分配&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td width="164" valign="top"&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;停止执行&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td width="142" valign="top"&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;继续执行&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&lt;/span&gt;&amp;nbsp; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 如上图中显示，调用Stop后，结果中只能可能有一个大于5的结果，因为此时未分配和已分配的任务都被终止了，而当前任务并没有停止，继续执行打印语句，打印出来的只是当前的那个大于5的任务；&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 而调用Break后，结果中大于5的结果数量不定，因为当当前任务因满足大于5的条件，而触发Break后，其他已分配的任务并不会停止，即使它们包含大于5的任务，同样也会打印出来，这就是上图中第三幅图中，Break任务出现两个大于5的结果的原因！&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Stop和Break，它们的区别可以用下图表示：&lt;/span&gt; &lt;/p&gt;&lt;p align="center"&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/isline/201106/201106270916262284.png"&gt;&lt;span size="3" style="font-size: small;"&gt;&lt;img height="375" width="507" src="http://images.cnblogs.com/cnblogs_com/isline/201106/201106270916289418.png" alt="image" border="0" title="image" style="background-image: none; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 0px; border: 0px;" /&gt;&lt;/span&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 图中实现表示运行的任务，虚线表示任务运行过程中被终止。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;Section 2.线程安全&lt;/strong&gt;&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在并行计算中应当使用线程安全的类，例如有些时候我们需要不断迭代形成一个集合组织，这个集合可能是一个列表，在普通程序中List&amp;lt;T&amp;gt;完全可以完成这个任务，但是如果在并行计算中使用List&amp;lt;T&amp;gt;的add方法，就会出现一些错误，这些错误是随机的，也就是说有时候并不出现。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 以下代码：&lt;/span&gt; &lt;b&gt;&lt;span size="3" style="font-size: small;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;List&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; ls &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; List&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(); &lt;br /&gt;&lt;br /&gt;Parallel.For(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;10000&lt;/span&gt;&lt;span style="color: #000000;"&gt;, (i) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;{ &lt;br /&gt;&lt;br /&gt;  ls.Add(i.ToString()); &lt;br /&gt;&lt;br /&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 以上代码偶尔会出现错误，出现错误的概率随着循环次数和并行任务的增加而增大，类似代码需求可以使用ConcurrentBag&amp;lt;T&amp;gt;来代替，针对并行计算提供的类库请参照MSDN：&lt;/span&gt;&lt;a href="http://msdn.microsoft.com/zh-cn/library/dd287108.aspx"&gt;&lt;span size="3" style="font-size: small;"&gt;http://msdn.microsoft.com/zh-cn/library/dd287108.aspx&lt;/span&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 提示：并行计算并不是天上掉下的馅饼，它不是所有时候都比串行程序快，因为并行总要付出一些额外的代价，比如任务分配、任务同步、任务通讯等，到底什么时候才能放心的吃掉这个馅饼，需要仔细地设计算法，并且应该在多台典型的服务器环境中进行测试、对比，这是一个比较烦人的过程，但是最终得到的结果可能会改变你的设计思路。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&lt;/span&gt;&amp;nbsp; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;具体可以参考我的文章：&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/isline/archive/2011/04/20/2022228.html"&gt;&lt;span size="3" style="font-size: small;"&gt;DotNet并行计算的使用误区(一)&lt;/span&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/isline/archive/2011/04/20/2022228.html"&gt;&lt;span size="3" style="font-size: small;"&gt;http://www.cnblogs.com/isline/archive/2011/04/20/2022228.html&lt;/span&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/isline/archive/2011/04/21/2023137.html"&gt;&lt;span size="3" style="font-size: small;"&gt;DotNet并行计算的使用误区(二)&lt;/span&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;http://www.cnblogs.com/isline/archive/2011/04/21/2023137.html&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/isline/aggbug/2091079.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/isline/archive/2011/06/27/2091079.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/isline/archive/2011/05/10/2041822.html</id><title type="text">ToList&amp;lt;&amp;gt;()所带来的性能影响</title><summary type="text">前几天优化师弟写的代码，有一个地方给我留下很深刻的印象，就是我发现他总是将PLINQ的结果ToList()，然后再返回给主程序，对于这一点我十分不解，于是去问他是什么原因，得到的答案很幽默:因为习惯。 最终优化方案很简单，去掉了ToList和Count，改用其他方法代替，程序从几天的运行时间一下缩短到几个小时。</summary><published>2011-05-10T01:32:00Z</published><updated>2011-05-10T01:32:00Z</updated><author><name>Aicken(李鸣)</name><uri>http://www.cnblogs.com/isline/</uri></author><link rel="alternate" href="http://www.cnblogs.com/isline/archive/2011/05/10/2041822.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/isline/archive/2011/05/10/2041822.html"/><content type="html">&amp;nbsp;&amp;nbsp;&amp;nbsp; 前几天优化师弟写的代码，有一个地方给我留下很深刻的印象，就是我发现他总是将PLINQ的结果ToList&amp;lt;&amp;gt;()，然后再返回给主程序，对于这一点我十分不解，于是去问他是什么原因，得到的答案很幽默:因为习惯。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 有时候对于方法的不甚了解加上&amp;ldquo;习惯&amp;rdquo;，往往是程序性能和稳定性终结者，就拿这个Case来说吧，原始代码如下：&lt;br /&gt;&lt;div class="dp"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;a href="http://www.cnblogs.cc2/#"&gt;&lt;/a&gt;&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;var query = from cr in LCRNormal.AsParallel()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; let listId = from crt in LCRNormal&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; group crt by crt.KeyValue into m&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select m.Max(n =&amp;gt; n.DBID)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; where listId.Contains(cr.DBID) &amp;amp;&amp;amp; !cr.IsRegularRecord &amp;amp;&amp;amp; cr.Status != 3&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select new ComputingResultForTemp()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; KeyValue = cr.KeyValue,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DBID = cr.DBID,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Status = cr.Status&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;/p&gt;&lt;p&gt;query.ToList&amp;lt;ComputingResultForTemp&amp;gt;();&lt;/p&gt;&amp;nbsp;&amp;nbsp;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 经过以上PLINQ后，泛型列表中大概还剩下60万至100万条数据，然后我们这位师弟做了两个很&amp;ldquo;施瓦辛格&amp;rdquo;的动作：ToList&amp;lt;&amp;gt;()和Count()，测试程序运行在一台4*2G HZ，12GB内存的服务器上，竟然跑了2天多！我觉得正式这两个方法导致了程序性能的降低，为了&amp;nbsp; 确定我的判断，我分别在以上代码、ToList&amp;lt;&amp;gt;()和Count()周围加上了StopWatch计时器，然后将结果以文本的形式输出：&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ●&amp;nbsp;100万数据PLINQ查询：&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ==========3/26/2011 01:34:31 PM ===========&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; **(GetDeletedRecords)Start PLINQ(LINQ FITTER)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;==========3/26/2011 01:38:38 PM ===========&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; **(GetDeletedRecords)Finish PLINQ (LINQ FITTER)&lt;br /&gt;&amp;nbsp;&amp;nbsp; ●&amp;nbsp; 80万数据ToList &amp;lt;&amp;gt;()：&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;==========3/26/2011 03:22:10 PM ===========&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;**(GetDeletedRecords)Start Get List&lt;br /&gt;●&amp;nbsp; 80万数据Count()：&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;==========3/28/2011 02:12:09 PM ===========&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;**(GetDeletedRecords)Start Get Count&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;==========3/28/2011 08:50:55 PM ===========&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;** (GetDeletedRecords)Finish Get Count&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 日志格式是这样：任务开始时输出当前时间和&amp;ldquo;Start&amp;rdquo;，任务结束时输出&amp;ldquo;Finish&amp;rdquo;，当从日志中可以看出，PLINQ的效率还是很高的，只运行了几分钟；ToList&amp;lt;&amp;gt;()方法在运行了1天多后人为终止，所以只有Start没有Finish；Count()方法也运行了6小时多。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 所以最终优化方案很简单，去掉了ToList和Count，改用其他方法代替，程序从几天的运行时间一下缩短到几个小时。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 我是Aicken(李鸣),欢迎您关注我的下一篇文章&lt;/p&gt;&lt;img src="http://www.cnblogs.com/isline/aggbug/2041822.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/isline/archive/2011/05/10/2041822.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/isline/archive/2011/04/21/2023137.html</id><title type="text">DotNet并行计算的使用误区(二)</title><summary type="text">从网上很多已经发布的并行计算的例子来讲，有很多存在一定的误区甚至是误导，这导致了一线编程人员产生一些错误的思路，它们多是通过示例讲述并行计算的性能优越性，似乎程序人员可以不费吹灰之力就能将程序性能提升N倍，如果这些想法没有经过比较就应用于实际，那么就会造成一定的损失</summary><published>2011-04-21T00:56:00Z</published><updated>2011-04-21T00:56:00Z</updated><author><name>Aicken(李鸣)</name><uri>http://www.cnblogs.com/isline/</uri></author><link rel="alternate" href="http://www.cnblogs.com/isline/archive/2011/04/21/2023137.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/isline/archive/2011/04/21/2023137.html"/><content type="html">&lt;p&gt;&lt;strong&gt;上接 &lt;a target="_blank" href="http://www.cnblogs.com/isline/archive/2011/04/20/2022228.html"&gt;DotNet并行计算的使用误区(一)&lt;/a&gt;&lt;/strong&gt; &lt;/p&gt;&lt;p&gt;&lt;strong&gt;● 误区三 . 并行计算是运行时的事&lt;/strong&gt; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 的确，DotNet会在运行时决定是否使用并行库处理代码，但是早在你编译代码时，编译器就早已为这一时刻做好准备，换就话说： &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1. 使用并行库处理代码与普通方式对比，IL的结构是不同的。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2. 即使你选择使用并行计算，并且你也确实拥有多核﻿﻿(线程)CPU，运行时你的代码也不一定是并行的。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 使用TPL后CLR可能会分解任务，这一依据的其中之一是由IL支持的，IL将并行的任务代码分离，以便在将来的操作中并行，这一点可以从以下的示例中看出来，以下两段示例的核心C#代码都是Tostring()和Sleep()，Code A使用For包含Sleep，Code B使用Parallel.For处理： &lt;/p&gt;&lt;p&gt;Code Part A： &lt;/p&gt;&lt;p&gt;IL： &lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;IL_000e: callvirt instance &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; [System]System.Diagnostics.Stopwatch::Start() &lt;br /&gt;&lt;br /&gt;IL_0013: nop &lt;br /&gt;&lt;br /&gt;IL_0014: ldc.i4.&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;IL_0015: stloc.&lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;IL_0016: br.s IL_0031 &lt;br /&gt;&lt;br /&gt;IL_0018: nop &lt;br /&gt;&lt;br /&gt;IL_0019: ldloca.s i &lt;br /&gt;&lt;br /&gt;&lt;span style="color: #ff6600;"&gt;IL_001b: call instance &lt;/span&gt;&lt;/span&gt;&lt;span style="color: #ff6600;"&gt;string [mscorlib]System.Int32::ToString() &lt;br /&gt;&lt;br /&gt;IL_0020: stloc.0 &lt;br /&gt;&lt;br /&gt;IL_0021: ldc.i4 0xc8 &lt;br /&gt;&lt;br /&gt;IL_0026: call void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;span style="color: #ff6600;"&gt; [mscorlib]System.Threading.Thread::Sleep(int32) &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;IL_002b: nop &lt;br /&gt;&lt;br /&gt;IL_002c: nop &lt;br /&gt;&lt;br /&gt;IL_002d: ldloc.&lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;IL_002e: ldc.i4.&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;IL_002f: add &lt;br /&gt;&lt;br /&gt;IL_0030: stloc.&lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;IL_0031: ldloc.&lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;IL_0032: ldc.i4.s &lt;/span&gt;&lt;span style="color: #800080;"&gt;10&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;IL_0034: clt &lt;br /&gt;&lt;br /&gt;IL_0036: stloc.&lt;/span&gt;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;IL_0037: ldloc.&lt;/span&gt;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;IL_0038: brtrue.s IL_0018 &lt;br /&gt;&lt;br /&gt;IL_003a: ldloc.&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;IL_003b: callvirt instance &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; [System]System.Diagnostics.Stopwatch::Stop() &lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;我们注意到，Code Part A的Sleep是直接出现在Load方法中的。 &lt;/p&gt;&lt;p align="center"&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/isline/201104/201104210856229946.jpg"&gt;&lt;img height="224" width="452" src="http://images.cnblogs.com/cnblogs_com/isline/201104/201104210856235735.jpg" alt="clip_image004" border="0" title="clip_image004" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 再来看看Parallel方式： &lt;/p&gt;&lt;p&gt;Code Part B： &lt;/p&gt;&lt;p&gt;Form1_Load: &lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" style="width: 892px; height: 681px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;IL_0019: callvirt instance &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; [System]System.Diagnostics.Stopwatch::Start() &lt;br /&gt;&lt;br /&gt;IL_001e: nop &lt;br /&gt;&lt;br /&gt;IL_001f: ldc.i4.&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;IL_0020: ldc.i4.s &lt;/span&gt;&lt;span style="color: #800080;"&gt;10&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;IL_0022: ldloc.&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;IL_0023: ldftn instance &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; WindowsFormsApplication4.Form1&lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;lt;&amp;gt;c__DisplayClass1&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;::&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;lt;Form1_Load&amp;gt;&lt;span style="color: #ff6600;"&gt;b__0&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;(int32) &lt;br /&gt;&lt;br /&gt;IL_0029: newobj instance &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; [mscorlib]System.Action`&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;int32&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;::.ctor(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;br /&gt;&lt;br /&gt;native &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;br /&gt;&lt;br /&gt;IL_002e: call valuetype [mscorlib]System.Threading.Tasks.ParallelLoopResult [mscorlib]System.Threading.Tasks.Parallel::For(int32, &lt;br /&gt;&lt;br /&gt;int32, &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; [mscorlib]System.Action`&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;int32&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;br /&gt;&lt;br /&gt;IL_0033: pop &lt;br /&gt;&lt;br /&gt;IL_0034: ldloc.&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;IL_0035: callvirt instance &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; [System]System.Diagnostics.Stopwatch::Stop() &lt;br /&gt;&lt;br /&gt;&lt;span style="color: #ff6600;"&gt;注意红色字体，Sleep已经不在Load方法中了，而是被一个&amp;ldquo;b__0&amp;rdquo;代替，并行代码与宿主代码分离，以下就是b__0的IL： &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;.method &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; hidebysig instance &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;lt;Form1_Load&amp;gt;b__0&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;(int32 i) cil managed &lt;br /&gt;&lt;br /&gt;{ &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 代码大小 26 (0x1a) &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;.maxstack &lt;/span&gt;&lt;span style="color: #800080;"&gt;8&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;IL_0000: nop &lt;br /&gt;&lt;br /&gt;IL_0001: ldarg.&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;IL_0002: ldarga.s i &lt;br /&gt;&lt;br /&gt;IL_0004: call instance &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; [mscorlib]System.Int32::ToString() &lt;br /&gt;&lt;br /&gt;IL_0009: stfld &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; WindowsFormsApplication4.Form1&lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;lt;&amp;gt;c__DisplayClass1&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;::a &lt;br /&gt;&lt;br /&gt;IL_000e: ldc.i4 &lt;/span&gt;&lt;span style="color: #800080;"&gt;0xc8&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;IL_0013: call &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; [mscorlib]System.Threading.Thread::Sleep(int32) &lt;br /&gt;&lt;br /&gt;IL_0018: nop &lt;br /&gt;&lt;br /&gt;IL_0019: ret &lt;br /&gt;&lt;br /&gt;} &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; end of method '&amp;lt;&amp;gt;c__DisplayClass1'::'&amp;lt;Form1_Load&amp;gt;b__0' &lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 结构图： &lt;/p&gt;&lt;p align="center"&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/isline/201104/201104210856243717.jpg"&gt;&lt;img height="224" width="605" src="http://images.cnblogs.com/cnblogs_com/isline/201104/201104210856243651.jpg" alt="clip_image006" border="0" title="clip_image006" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp; 以上的红色代码就是在Code A中出现的主要代码。再让我们重温一下这张图，IL的代码任务已经很明显的指示了出来。 &lt;/p&gt;&lt;p align="center"&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/isline/201104/201104210856257173.jpg"&gt;&lt;img height="267" width="497" src="http://images.cnblogs.com/cnblogs_com/isline/201104/201104210856269059.jpg" alt="clip_image007" border="0" title="clip_image007" style="background-image: none; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 0px; border: 0px;" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 每当我们增加一个并行代码段，IL中就会增加一个b_N块：假如我们的代码中包含两个Parallel块，每块的主代码与上述一致，IL如下： &lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" style="width: 819px; height: 573px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;IL_0019: callvirt instance &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; [System]System.Diagnostics.Stopwatch::Start() &lt;br /&gt;&lt;br /&gt;IL_001e: nop &lt;br /&gt;&lt;br /&gt;IL_001f: ldc.i4.&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;IL_0020: ldc.i4.s &lt;/span&gt;&lt;span style="color: #800080;"&gt;10&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;IL_0022: ldloc.&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;IL_0023: ldftn instance &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; WindowsFormsApplication4.Form1&lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;lt;&amp;gt;c__DisplayClass2&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;::&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;lt;Form1_Load&amp;gt;&lt;span style="color: #ff6600;"&gt;b__0&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #ff6600;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;(int32) &lt;br /&gt;&lt;br /&gt;IL_0029: newobj instance &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; [mscorlib]System.Action`&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;int32&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;::.ctor(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;br /&gt;&lt;br /&gt;native &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;br /&gt;&lt;br /&gt;IL_002e: call valuetype [mscorlib]System.Threading.Tasks.ParallelLoopResult [mscorlib]System.Threading.Tasks.Parallel::For(int32, &lt;br /&gt;&lt;br /&gt;int32, &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; [mscorlib]System.Action`&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;int32&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;br /&gt;&lt;br /&gt;IL_0033: pop &lt;br /&gt;&lt;br /&gt;IL_0034: ldc.i4.&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;IL_0035: ldc.i4.s &lt;/span&gt;&lt;span style="color: #800080;"&gt;10&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;IL_0037: ldloc.&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;IL_0038: ldftn instance &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; WindowsFormsApplication4.Form1&lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;lt;&amp;gt;c__DisplayClass2&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;::&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;lt;Form1_Load&amp;gt;&lt;span style="color: #ff6600;"&gt;b__1&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #ff6600;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;(int32) &lt;br /&gt;&lt;br /&gt;IL_003e: newobj instance &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; [mscorlib]System.Action`&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;int32&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;::.ctor(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;br /&gt;&lt;br /&gt;native &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;br /&gt;&lt;br /&gt;IL_0043: call valuetype [mscorlib]System.Threading.Tasks.ParallelLoopResult [mscorlib]System.Threading.Tasks.Parallel::For(int32, &lt;br /&gt;&lt;br /&gt;int32, &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; [mscorlib]System.Action`&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;int32&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;br /&gt;&lt;br /&gt;IL_0048: pop &lt;br /&gt;&lt;br /&gt;IL_0049: ldloc.&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;IL_004a: callvirt instance &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; [System]System.Diagnostics.Stopwatch::Stop() &lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 下图中会有对应模块出现： &lt;/p&gt;&lt;p align="center"&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/isline/201104/201104210856267041.jpg"&gt;&lt;img height="227" width="544" src="http://images.cnblogs.com/cnblogs_com/isline/201104/201104210856275339.jpg" alt="clip_image009" border="0" title="clip_image009" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 上面的例子说明，在IL阶段已经为运行时的并行执行任务做了准备，编译阶段将并行任务从宿主中分离出来，运行阶段决定是否采用并行方式执行任务。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/isline/aggbug/2023137.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/isline/archive/2011/04/21/2023137.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/isline/archive/2011/04/20/2022228.html</id><title type="text">DotNet并行计算的使用误区(一)</title><summary type="text">从网上很多已经发布的并行计算的例子来讲，有很多存在一定的误区甚至是误导，这导致了一线编程人员产生一些错误的思路，它们多是通过示例讲述并行计算的性能优越性，似乎程序人员可以不费吹灰之力就能将程序性能提升N倍，如果这些想法没有经过比较就应用于实际，那么就会造成一定的损失。这篇文章就来聊聊关于合理使用并行计算的问题，供大家参考。</summary><published>2011-04-20T05:59:00Z</published><updated>2011-04-20T05:59:00Z</updated><author><name>Aicken(李鸣)</name><uri>http://www.cnblogs.com/isline/</uri></author><link rel="alternate" href="http://www.cnblogs.com/isline/archive/2011/04/20/2022228.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/isline/archive/2011/04/20/2022228.html"/><content type="html">&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 并行计算无疑是.Net Framework平台的一大亮点，它自动的将一个任务分解，并以并发的形式执行，程序员不用操心各任务之间的协作和同步问题，这使得可以更加专注于业务的实现。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; .NET 中的 &lt;b&gt;TPL(Task Parallel Library)&lt;/b&gt;，中文意思是任务并行库，它的设计是为了能更简单地编写可自动使用多处理器的托管代码。使用该库，用户可以非常方便地用现有序列代码表达潜在并行性，这样序列代码中公开的并行任务将会在所有可用的处理器上同时运行，通常这会大大提高速度。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 但是，从网上很多已经发布的并行计算的例子来讲，有很多存在一定的误区甚至是误导，这导致了一线编程人员产生一些错误的思路，它们多是通过示例讲述并行计算的性能优越性，似乎程序人员可以不费吹灰之力就能将程序性能提升N倍，如果这些想法没有经过比较就应用于实际，那么就会造成一定的损失。这篇文章就来聊聊关于合理使用并行计算的问题，供大家参考，这些误区主要包括：&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp; 1. 只要使用并行就会提高程序性能&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp; 2. 并行循环嵌套越多程序性能越高&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp; 3. 并行计算是运行时的事&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp; 下面让我们来一个个的讲解这些误会。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;strong&gt;&lt;span style="font-size: 15px;"&gt; ● 误区一 .只要使用并行就会提高程序性能&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 实时并不是这样，实际上并行计算的使用对前提要求非常严格，一般情况大&lt;/span&gt;&lt;span size="3" style="font-size: small;"&gt;量使用并行计算不但不会提升性能，反而会适得其反，下面有两个Case给大家说明。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Case 1. &lt;/b&gt;&lt;b&gt;使用&lt;/b&gt;&lt;b&gt;Thread&lt;/b&gt;&lt;b&gt;.&lt;/b&gt;&lt;b&gt;Sleep()&lt;/b&gt;&lt;b&gt;比较并行与单行程序的性能并不客观。&lt;/b&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在许多并行计算与单行方式程序性能比较的例子中，很多都包含类似Thread.Sleep&lt;b&gt;()&lt;/b&gt;的语句，运行这样的Demo我们确实看到，并行的时间结果竟然提升如此许多，但是你有没有仔细研究一下时间降低的原因呢？&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 有如下两段代码：&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Code Part A：&lt;/span&gt; &lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;10&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;br /&gt;&lt;br /&gt;{ &lt;br /&gt;&lt;br /&gt;a &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; i.ToString(); &lt;br /&gt;&lt;br /&gt;Thread.Sleep(&lt;/span&gt;&lt;span style="color: #800080;"&gt;200&lt;/span&gt;&lt;span style="color: #000000;"&gt;); &lt;br /&gt;&lt;br /&gt;} &lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp; Code Part B：&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;Parallel.For(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;10&lt;/span&gt;&lt;span style="color: #000000;"&gt;, (i) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;{ &lt;br /&gt;&lt;br /&gt;a &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; i.ToString(); &lt;br /&gt;&lt;br /&gt;Thread.Sleep(&lt;/span&gt;&lt;span style="color: #800080;"&gt;200&lt;/span&gt;&lt;span style="color: #000000;"&gt;); &lt;br /&gt;&lt;br /&gt;}); &lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在我的双核本机上，测试结果是令人兴奋的：Code Part A跑了2秒多，而Code Part B只跑了800多毫秒，时间大幅降低，然而这样你就决定将你的代码迁移到并行方式吗？&lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 我建议你还是等等再说吧，Code Part B比A具有更高性能的原因不是因为主代码并行而带来的性能提升，而是由于Sleep()，在并行环境中，任务实际上只是休息了1/N（N为并行数量），而不是单行程序中的全部，这是因为TPL将循环工作分解的缘故，在双核本机上，Code Part B相当于2个5次的循环同时进行，Sleep()又很少有共享资源的消耗，不需要与其他进程同步，所以运行时间比1次10次的循环降低了，假如我们去掉Code Part A、B中的Sleep语句，那么结果又是如何呢？答案是两者十分趋近。实际上在主代码短短小的情况下，并行计算会表现出一定的性能不稳定性，这里留一点，感兴趣的朋友自己测试一下吧。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 选择并行计算处理问题，首先要保证你的样本或需求适合并行处理，比如写排序算法时就不能使用并行计算。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&lt;b&gt;&amp;nbsp; Case 2: &lt;/b&gt;&lt;b&gt;并行程序对于字符串与数字的处理效率是不同的。&lt;/b&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @ 字符串累加：&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 单行：&lt;/span&gt; &lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;100000&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;br /&gt;&lt;br /&gt;{ &lt;br /&gt;&lt;br /&gt;a &lt;/span&gt;&lt;span style="color: #000000;"&gt;+=&lt;/span&gt;&lt;span style="color: #000000;"&gt; i.ToString(); &lt;br /&gt;&lt;br /&gt;} &lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 并行：&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;Parallel.For(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;100000&lt;/span&gt;&lt;span style="color: #000000;"&gt;, (i) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;{ &lt;br /&gt;&lt;br /&gt;a &lt;/span&gt;&lt;span style="color: #000000;"&gt;+=&lt;/span&gt;&lt;span style="color: #000000;"&gt; i.ToString(); &lt;br /&gt;&lt;br /&gt;}); &lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @ 字符串比较：&lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 单行：&lt;/span&gt; &lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;100000&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;br /&gt;&lt;br /&gt;{ &lt;br /&gt;&lt;br /&gt;f &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; a.Equals(i.ToString()); &lt;br /&gt;&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 并行：&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;Parallel.For(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;100000&lt;/span&gt;&lt;span style="color: #000000;"&gt;, (i) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;{ &lt;br /&gt;&lt;br /&gt;f &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; a.Equals(i.ToString()); &lt;br /&gt;&lt;br /&gt;}); &lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @ 数字比较：&lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 单行：&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;100000000&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;br /&gt;&lt;br /&gt;{ &lt;br /&gt;&lt;br /&gt;f &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; j; &lt;br /&gt;&lt;br /&gt;} &lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 并行：&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #000000;"&gt;Parallel.For(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;/span&gt;&lt;span style="color: #800080;"&gt;100000000&lt;/span&gt;&lt;span style="color: #000000;"&gt;, (i) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;br /&gt;&lt;br /&gt;{ &lt;br /&gt;&lt;br /&gt;f &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; j; &lt;br /&gt;&lt;br /&gt;}); &lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 运行以上三段测试代码可知，TPL对于字符串处理还是很令人满意的。所以不是所有情况都适合使用TPL库处理程序，这一点对于程序中的遍历情景很重要，在使用PLINQ时，建议先分析样本空间的类型与具体操作，再决定使用哪种计算。&lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ●&lt;span style="font-size: 15px;"&gt;&lt;strong&gt;&amp;nbsp; 误区二.并行循环嵌套越多程序性能越高&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 对于两层以上循环的代码段，在你决定使用并行前，先要做的是发现这段代&lt;/span&gt;&lt;span size="3" style="font-size: small;"&gt;码的主要耗损在哪，是在外层还是在内层，只有评估当并行对性能带来的提升大于损耗时，再重构为并行也不迟，因为TPL在很多情形都提供了并行支持，很多程序员在能用到并行的地方都用并行，而没有经过测试比较，实际上有很多时候，在所有的地方加上并行特性，程序的性能反而会受到损失，这里就不在给出案例了。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 从下图可以看出，TPL虽然自动管理了循环中的对象，但是这些&amp;ldquo;自动&amp;rdquo;是有一些性能损失的，如果我们的代码中不断地要求TPL进行对象的拆分、合并、同步，而忽视了业务本身的优化，那无疑是对性能不利的。&lt;/span&gt; &lt;/p&gt;&lt;p align="center"&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/isline/201104/201104201359043185.jpg"&gt;&lt;span size="3" style="font-size: small;"&gt;&lt;/span&gt;&lt;a&gt;&lt;/a&gt;&lt;a&gt;&lt;/a&gt;&lt;/a&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/isline/201104/20110420135905611.jpg"&gt;&lt;img height="325" width="606" src="http://images.cnblogs.com/cnblogs_com/isline/201104/201104201359052497.jpg" alt="clip_image002" border="0" title="clip_image002" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在这里Aicken给出一个建议，就是在并行前，先要评估这段代码的任务量有多大，有没有必要并行？这段代码有没有对磁盘等&amp;ldquo;写&amp;rdquo;要求的竞争？代码是处理什么任务的，以及代码的运行环境是否支持并行；再者就是代码重构后进行性能测试，这样才能保证并行计算有意义。&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 其实，用对并行计算除了对性能的提升外，还有一点可贵的地方，就是对代码的重构，简洁而富有结构性的代码，更加符合编码进步的要求，不是吗？&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span size="3" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; （待续）&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/isline/aggbug/2022228.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/isline/archive/2011/04/20/2022228.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/isline/archive/2011/04/13/2015035.html</id><title type="text">ITIL基础概述与实战案例分析(下)</title><summary type="text">上一篇文章主要给大家介绍了“基于ITIL体系的IT部门建设”，下面举几个例子，来说明ITIL实施后的效果。</summary><published>2011-04-13T08:52:00Z</published><updated>2011-04-13T08:52:00Z</updated><author><name>Aicken(李鸣)</name><uri>http://www.cnblogs.com/isline/</uri></author><link rel="alternate" href="http://www.cnblogs.com/isline/archive/2011/04/13/2015035.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/isline/archive/2011/04/13/2015035.html"/><content type="html">&lt;p&gt;上一篇文章主要给大家介绍了&amp;ldquo;&lt;b&gt;基于&lt;/b&gt;&lt;b&gt;ITIL&lt;/b&gt;&lt;b&gt;体系的&lt;/b&gt;&lt;b&gt;IT&lt;/b&gt;&lt;b&gt;部门建设&lt;/b&gt;&amp;rdquo;，下面举几个例子，来说明ITIL实施后的效果。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ● &lt;b&gt;基于&lt;/b&gt;&lt;b&gt;ITIL&lt;/b&gt;&lt;b&gt;体系的&lt;/b&gt;&lt;b&gt;IT&lt;/b&gt;&lt;b&gt;项目管理&lt;/b&gt;&lt;b&gt;&lt;/b&gt; &lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;/b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 任何项目的上线都会启动对项目运维的环节，而这个环节的重要性往往超过项目管理的任何一个环节，因为这是&amp;ldquo;结果导向&amp;rdquo;管理思想的最终成果环节。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 这里我想以电子商务项目为例，引入ITIL的&amp;ldquo;服务台职能(Service Desk Function)&amp;rdquo;来完善电子商务的运营体系。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 这个职能处理了用户故障、问题请求与对其的处理、反馈跟进的方法，在这个方法中包括了事故管理、问题管理、配置管理、变更管理、发布管理6个流程，即当用户发起提问时(提问可能包括：系统使用困难、系统故障、系统改进建议、业务问题咨询等)，IT支持、技术与管理部门如何处理。这个职能是一个入口，&amp;ldquo;服务台职能&amp;rdquo;实施的程度直接体现了一个公司ITIL体系的建设程度。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 以电子商务系统为例，用户遇到使用中的问题(可能是下单、付款等)，首先是服务台一线的服务人员，由服务人员从资源库中使用经验解答用户问题，如果一线人员无法解决问题，会将问题派发至内部工程师，由工程师解决，解决问题后将问题记录至知识库，供下次检索。 &lt;/p&gt;&lt;p align="center"&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/isline/201104/201104131648279452.jpg"&gt;&lt;img height="384" width="472" src="http://images.cnblogs.com/cnblogs_com/isline/201104/20110413164849334.jpg" alt="clip_image002[4]_thumb[1]_thumb[1]" border="0" title="clip_image002[4]_thumb[1]_thumb[1]" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p align="center"&gt;图2 服务台整体运作流程 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 实际上，这套方法的核心在于使用一线人员提供快速的服务，使用二线人员提供可靠地服务，一线与二线人员之间的交互方式、提供服务的质量可以根据SLAs设定，即根据矩阵图提供不同等级的服务。 &lt;/p&gt;&lt;p align="center"&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/isline/201104/201104131648535158.jpg"&gt;&lt;img height="185" width="226" src="http://images.cnblogs.com/cnblogs_com/isline/201104/201104131648538255.jpg" alt="clip_image004_thumb[3]_thumb[2]" border="0" title="clip_image004_thumb[3]_thumb[2]" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p align="center"&gt;图3 分度图 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 最先要解决的是第一象限的工作，实际上ITIL已经为IT部门规划了很多工作的分类，供CIO或ITIL实施人员参考，例如以下两个事件：总经理需要打印一份文档，可是打印机没有就绪；公司网络中断，造成至少10人无法访问办公系统。这个案例中事件一为第一象限工作，事件二为第三象限工作，有了这个参考，结合我们的企业文化，我们就可以更好的处理问题了，这只是一个例子。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Case 1. 电子商务订单查询不符 &lt;/p&gt;&lt;p&gt;以下案例简单叙述了电子商务系统运营中，用户查询业绩的一个小例子，该例子说明一线客服怎样配合用户解决问题，与解决问题后客服人员所作的工作。 &lt;/p&gt;&lt;p align="center"&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/isline/201104/201104131648578967.png"&gt;&lt;img height="490" width="425" src="http://images.cnblogs.com/cnblogs_com/isline/201104/201104131648582098.png" alt="image_thumb[15]_thumb[1]" border="0" title="image_thumb[15]_thumb[1]" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在这个案例中，用户问题并未调用内部工程师资源，而是重复利用了知识库的资源，完成了用户的服务工作。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 所以，ITIL建议将用户问题在一线人员那里得到解决，而一线人员依靠的是个人经验和知识库，知识库是系统问题解决的沉淀，我们的客服模式在解决问题后，应该录入相关问题，将问题变为知识。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Case 2. 电子商务账号余额无法付款 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 下面这个流程显示了如何快速解决系统难题的流程与一线、二线工程师沟通方案。 &lt;/p&gt;&lt;p align="center"&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/isline/201104/201104131648595785.png"&gt;&lt;img height="566" width="526" src="http://images.cnblogs.com/cnblogs_com/isline/201104/201104131648597280.png" alt="image_thumb[17]_thumb[2]" border="0" title="image_thumb[17]_thumb[2]" style="background-image: none; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 0px; border: 0px;" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 该套方法不仅仅适用于电子商务，而且ITIL在ERP、系统集成方面同样有比较成熟的解决方案。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Case 3.ERP 出库流程变更 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 该案例模拟了将出库流程变更为新流程的流程，该流程适用于代码更新、系统发布等事件。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 例：原始ERP出库单如下： &lt;/p&gt;&lt;p align="center"&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/isline/201104/201104131649002886.png"&gt;&lt;img height="435" width="474" src="http://images.cnblogs.com/cnblogs_com/isline/201104/20110413164900443.png" alt="image_thumb[12]_thumb[2]" border="0" title="image_thumb[12]_thumb[2]" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp; 在ITIL中，如果需要对现有系统做出变更，需要以下流程的支持: &lt;/p&gt;&lt;p align="center"&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/isline/201104/201104131649019081.png"&gt;&lt;img height="122" width="482" src="http://images.cnblogs.com/cnblogs_com/isline/201104/2011041316490219.png" alt="image_thumb[7]_thumb[1]" border="0" title="image_thumb[7]_thumb[1]" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 配置管理是识别和确认系统的配置项，记录和报告配置项状态和变更请求，检验配置项的正确性和完整性等活动构成的过程。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 变更管理是指为在最短的中断时间内完成基础架构或服务的任一方面的变更而对其进行控制的服务管理流程。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 发布管理是指对经过测试后导入实际应用的新增或修改后的配置项进行分发和宣传的管理流程。发布管理以前又称为软件控制与分发，它由变更管理流程控制。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 经过以上步骤，ERP新版出库单增加了拣货流程，修改为： &lt;/p&gt;&lt;p align="center"&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/isline/201104/201104131649029213.png"&gt;&lt;img height="415" width="364" src="http://images.cnblogs.com/cnblogs_com/isline/201104/20110413164903151.png" alt="image_thumb[11]_thumb[1]" border="0" title="image_thumb[11]_thumb[1]" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ITIL的变更控制，不仅仅适用于一些既有系统的维护与更新，还是用于一些开发、测试、发布、上线工作的标准化管理，比如我们的IT项目的需求变更、测试发布等工作。 &lt;/p&gt;&lt;p&gt;李鸣(aicken)原创 转载注明&lt;/p&gt;&lt;img src="http://www.cnblogs.com/isline/aggbug/2015035.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/isline/archive/2011/04/13/2015035.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/isline/archive/2011/04/13/2014884.html</id><title type="text">ITIL基础概述与实战案例分析(上)</title><summary type="text">这篇文章将结合实例给大家介绍ITIL Foundation的管理方法和具体应用。目前ITIL Foundation主要有两个版本，分别是Vesion 2与Vesion 3，个人认为二者并不是取代关系，而是不同企业发展不同阶段的不同管理手法。</summary><published>2011-04-13T07:09:00Z</published><updated>2011-04-13T07:09:00Z</updated><author><name>Aicken(李鸣)</name><uri>http://www.cnblogs.com/isline/</uri></author><link rel="alternate" href="http://www.cnblogs.com/isline/archive/2011/04/13/2014884.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/isline/archive/2011/04/13/2014884.html"/><content type="html">&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 这篇文章将结合实例给大家介绍ITIL Foundation的管理方法和具体应用。目前ITIL Foundation主要有两个版本，分别是Vesion 2与Vesion 3，个人认为二者并不是取代关系，而是不同企业发展不同阶段的不同管理手法。 &lt;/p&gt;&lt;p&gt;&lt;b&gt;一．&lt;/b&gt;&lt;b&gt; &lt;/b&gt;&lt;b&gt;简述&lt;/b&gt;&lt;b&gt;ITIL&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ITIL，全称 Information Technology Infrastructure Library，译为&amp;ldquo;信息技术基础架构库&amp;rdquo;或&amp;ldquo;IT基础架构库&amp;rdquo;。 &lt;/p&gt;&lt;p&gt;ITIL适合那些业务领域多而杂的公司实施，它提供了一种简单的思路来处理复杂的问题，如果根据 ITIL进行 IT管理，至少有两方面的好处:一是所有纳入ITIL服务体系的业务部门都可以根据一套用业务语言描述的可量化的质量指标，降低与IT部门的沟通与工作Redo成本；二是IT部门可以提高服务质量、降低服务成本、降低项目沟通的成本，将需求与其变更定义在一个尽量清晰的范畴内，以一种相对正规的方式来运作项目，这样后面的IT管理方法(软件工程、系统集成标准)才能派上用场。 &lt;/p&gt;&lt;p&gt;&lt;b&gt;二．&lt;/b&gt;&lt;b&gt;Vesion2 VS Vesion3&lt;/b&gt; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在V2中更强调流程的管理，是IT管理的具体方法，它包括一个职能：服务台职能；十个流程：事件管理、问题管理、配置管理、变更管理、发布管理、服务级别、可用性、连续性、能力管理、财务管理。V2规范了IT对业务的服务提供和服务支持两条线，服务提供思路包括服务级别管理、可用性、连续性、能力管理、财务管理；服务支持思路包括事件管理、问题管理、配置管理、变更管理、发布管理。服务支持是服务提供的基础，服务提供是服务支持的改进思路。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在V3中该强调IT战略的梳理与落实方法，它是V2版本的精华并且加入了服务生命周期的概念，服务战略、服务设计、服务转换、服务运行、持续改进. &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;img height="298" width="330" src="http://images.cnblogs.com/cnblogs_com/isline/201104/201104131455231894.jpg" alt="clip_image002" border="0" title="clip_image002" /&gt; &lt;/p&gt;&lt;p align="center"&gt;图1 ITIL V3服务生命周期 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ITIL V3是V2版本的升华，它指出了流程并不是业务实现的全部，而只是其实现中的一部分，它可以影响业务实现，ITIL V3提到的IT服务管理包括决策、计划、设计、开发、测试、发布、运行和改进。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 不管是软件工程还是ITIL，都是将IT管理中不可见的因素可见化，不可控的因素可控化，离散的因素量化，耦合的因素聚合化。它们都是在决策分析、团队建设、项目管理、投资运营中的一种思想和问题处理方式。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 所以，实际上我觉得ITIL并不仅仅是针对IT的一种管理框架，它是企业管理的一种方法,这也正是ITIL V2的开发者英国商务部OGC的初衷。 &lt;/p&gt;&lt;p&gt;&lt;b&gt;三．基于&lt;/b&gt;&lt;b&gt;ITIL&lt;/b&gt;&lt;b&gt;思想的&lt;/b&gt;&lt;b&gt;IT&lt;/b&gt;&lt;b&gt;管理&lt;/b&gt;&lt;b&gt;&lt;/b&gt; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IT对业务的管理的风险不仅仅是在于技术，关键在于一个&amp;ldquo;变&amp;rdquo;字，无论是何种管理思想，都在围绕一个&amp;ldquo;变&amp;rdquo;字进行。有规则、有章法、有计划的&amp;ldquo;变&amp;rdquo;是变更，这种变化是正常的、可持续的，我管这种变称为&amp;ldquo;协变&amp;rdquo;；任意的、独立的、无计划的&amp;ldquo;变&amp;rdquo;是失控，是定时炸弹，我管这种变称为&amp;ldquo;逆变&amp;rdquo;，这种&amp;ldquo;变&amp;rdquo;经常在以下场景出现： &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 由业务部门单向发起，没有经过业务需求分析与系统设计分析两者同时认可的需求&amp;ldquo;变&amp;rdquo;化。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 出于某个操作或短期为了解决某个问题的需要，提出的&amp;ldquo;解决方案&amp;rdquo; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 为了结果的快速导向，过度的协调了IT资源(IT资源是指：人力、时间、资金、支持、知识等)中的某一个，而忽视了其他资源，导致被忽视资源所对应的项目环节的薄弱。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 实际上IT是为业务提供服务的部门，同时IT也是规整业务的部门，二者互相作用，IT对业务的支持不是按照业务部门的纯粹需要做纯粹的&amp;ldquo;服务&amp;rdquo;，而是要使用自己的专业知识，对需要进行加工，将&amp;ldquo;业务需要&amp;rdquo;变成&amp;ldquo;业务需求&amp;rdquo;，&amp;ldquo;业务需要&amp;rdquo;是不规整的、不可量化的、持续性低；&amp;ldquo;业务需求&amp;rdquo;是聚合的、可量化的、可持续的，这就是ITIL的真正本质的体现----即量化、流程、持续、改进。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 有规则、有章法、有计划的&amp;ldquo;变&amp;rdquo;是变更，这种变化是正常的、可持续的，这一点可以使用&amp;ldquo;服务支持&amp;rdquo;流程应对，即事故管理、问题管理、配置管理、变更管理和发布管理，这套流程指出了问题的生产者与消费者之间的关系，从一个问题的诞生到问题的解决都给予了&amp;ldquo;应该&amp;rdquo;做的解释。 &lt;/p&gt;&lt;p&gt;● &lt;b&gt;基于&lt;/b&gt;&lt;b&gt;ITIL&lt;/b&gt;&lt;b&gt;体系的&lt;/b&gt;&lt;b&gt;IT&lt;/b&gt;&lt;b&gt;部门建设&lt;/b&gt;&lt;b&gt;&lt;/b&gt; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ITIL是一套建设与改进事物的方法，这套方法最多的应用于IT建设，在这套思想体系中，最大的使用了职能、流程、规范、周期来描述IT的模型，也就是说按照以上四个关键字建立的IT体系，就是符合ITIL体系的。 &lt;/p&gt;&lt;p&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1.&lt;/b&gt;&lt;b&gt;职能建设：&lt;/b&gt;&lt;b&gt;&lt;/b&gt; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IT部门与职能建设，依据ITIL V3基本上分为：服务台职能(Service Desk Function)、运营管理职能(Operation Management Function)、技术管理(Technical Management Function)和应用管理(Application Management Function)。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 服务台职能(Service Desk Function)是ITIL中一个最成熟的职能，它的应用很广泛，该职能和事件、问题、配置、变更、发布五个流程在下一节再讲述其在项目中的应用。 &lt;/p&gt;&lt;p&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2.&lt;/b&gt;&lt;b&gt;流程建设&lt;/b&gt;&lt;b&gt;&lt;/b&gt; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ○ SLAs： &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 很多项目或部门再出现问题时都希望IT部门能尽早尽快的解决，但是IT的资源是有限的，总要解决那些&amp;ldquo;重要的、应该首先解决&amp;rdquo;的问题，那么什么是&amp;ldquo;重要的&amp;rdquo;呢？这就涉及到了ITIL的服务级别管理，它是为签订服务级别协议（SLAs）而进行的计划、报告和评价，说白了就是合同，它确保组织所需的IT服务质量在成本合理的范围内得以维持并逐渐提高。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ○ 财务管理： &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IT服务财务管理是负责预算和核算的，并向客户收取相应服务费用的管理流程，这个流程甚至细化到打印纸张都划入各部门预算。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IT服务财务管理流程产生的预算和核算信息可以为服务级别管理、能力管理、IT服务持续性管理和变更管理等管理流程提供决策依据。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ○ 持续性管理： &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IT服务持续性管理是指确保发生灾难后有足够的技术、财务和管理资源来确保IT服务持续性的管理流程，它关注的焦点是在发生服务故障后仍然能够提供预定级别的IT服务，从而支持组织的业务持续运作的能力。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ○ 能力管理： &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 能力管理是指在成本和业务需求的双重约束下，通过配置合理的服务能力使组织的IT资源发挥最大效能的服务管理流程。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ○ 可用性管理 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 可用性管理是通过分析用户和业务方的可用性需求，设计IT基础架构的可用性。它应该有意识的规避潜在的风险，避免过度设计。 &lt;/p&gt;&lt;p&gt;&amp;nbsp; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 李鸣(aicken)原创 转载注明&lt;/p&gt;&lt;img src="http://www.cnblogs.com/isline/aggbug/2014884.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/isline/archive/2011/04/13/2014884.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/isline/archive/2011/04/12/2013671.html</id><title type="text">The DotNet Garbage Collection</title><summary type="text">今天开始发第一篇英文原创博客《The DotNet Garbage Collection》</summary><published>2011-04-12T07:04:00Z</published><updated>2011-04-12T07:04:00Z</updated><author><name>Aicken(李鸣)</name><uri>http://www.cnblogs.com/isline/</uri></author><link rel="alternate" href="http://www.cnblogs.com/isline/archive/2011/04/12/2013671.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/isline/archive/2011/04/12/2013671.html"/><content type="html">&lt;p&gt;今天开始发第一篇英文原创博客《The DotNet Garbage Collection》&lt;/p&gt;&lt;p&gt;The Garbage Collection is a very important part of DotNet platform.Today we will talk about it. Think about if not GC,DotNet is also called a platform? Although both languages ​​are compiled into MSIL in dotnet, but when the recycling operation was "fighting each other", so that the programming will not only coding difficulty, but also make extremely complicated memory management ( language processing in different small differences, will be amplified in the recovery of resources), and it is not benefit to plantform transplanting.&lt;/p&gt;&lt;p&gt;This article will introduce the operation mode, algorithms, and associated of DotNet garbage collection ,and will show the key method of garbage collection. &lt;br /&gt;&lt;br /&gt;Speaking of garbage collection, very few people know, is not associated with Java garbage collection occurs, as early as in 1958, Turing Award winner John invented the Lisp language has been provided to the function of GC, which is the first time in GC, a flash of thought! Then, in 1984, Dave Ungar invented the first official language Small talk with a GC mechanism. &lt;br /&gt;&lt;br /&gt;. Net garbage collection is a big topic, if you did not come into contact with a similar language like C + +, it is difficult to understand how GC is an important and exciting things: &lt;br /&gt;&lt;br /&gt;1. To improve the cohesion of software systems. &lt;br /&gt;2. Reduce programming complexity, so that programmers do not have to deal with memory release. &lt;br /&gt;3. Without prejudice to the abstract system designers. &lt;br /&gt;4. Reduce the inappropriate use of memory produced by Bug. &lt;br /&gt;5. Success of the memory management managed to the runing time, changes loopholes in the management of unpredictable to can be estimated. &lt;br /&gt;&lt;br /&gt;Body:&lt;br /&gt;&lt;br /&gt;This chapter will introduce "GC algorithms and working methods"," GC coding method analysis ".&lt;br /&gt;&lt;br /&gt;Section. GC algorithms and working methods&lt;br /&gt;&lt;br /&gt;1. Algorithm&lt;br /&gt;&lt;br /&gt;&amp;nbsp; The nature of the garbage collector is tracking all references OF the object, reorganize the objects which is no longer be used ,release current memory.&lt;br /&gt;&lt;br /&gt;This sounds similar to something called the "reference count (Reference Counting) " algorithm, but this algorithm needs to traverse all the objects, and maintain their pointer, so some lower efficiency, and the problem of &amp;nbsp;"reference cycle" will &amp;ldquo;give you some jokes&amp;rdquo; at some time,the "reference cycle" is the reason of memory leak. So. Net used a technique called "mark and clear (Mark Sweep) " method to accomplish the above tasks.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;The algorithm of "Mark and clear ", the name suggests, has two skills:&lt;br /&gt;&lt;br /&gt;" Mark " skills - garbage identification: the root from the application, marking the using of reference and making relationship with each other, traversal all objects which be allocated on the HEAP, the no referenced object will not be marked, its becomes garbage; survival of the object is Marked, the CLR will make (maintenance) the objects to a "root - reachable object" chart. "&lt;br /&gt;&lt;br /&gt;In fact, CLR will maintenance those relations as a "tree", no doubt, the students understand data structures are known, structures of tree can up speed of traverse.&lt;br /&gt;&lt;br /&gt;Checking, marking an object reference, is a very interesting thing, there are many ways to do it, but only one is optimal efficiency,. Net finish it by the stack, in the process of input and output stack.&lt;/p&gt;&lt;p&gt;First in the tree, select an object which is survival, all references(in running time) of the object will be push stack, ok,and then, CLR start to find another survival objec and redo above step, until the stack is empty. Stacks become empty means that CLR have been traversaled all survival object of the local root (or a tree node). Tree nodes includes local variables (local variables will be recovered very quickly, because its scope is very clear and very easy to be controlled), register, static variables, these elements have to repeat this operation. Once completed, gc will check all objects one by one and mark referred objects, then some objects become garbage because it is not be marked.&lt;/p&gt;&lt;p align="left"&gt;"Clear" skills - release memory: Enabling Compact algorithm, move the survival objects, change their pointers to make it contiguous in memory, so the free memory contiguous too, and it solved the problem of memory fragmentation When re-allocate memory for other object, CLR do not have to searching the free space in a debris memory, so speed of allocation will be improved. &lt;/p&gt;&lt;p align="left"&gt;However, large objects (large object heap) except, GC will not move a giant in-memory, because it knows that the CPU is not cheap. Normally, large objects have a long lifetime, when a large object in the. NET managed heap generation, it is assigned to a special part of the heap, because the performance improved by move large objects less than arrange the heap special.&lt;br /&gt;&lt;br /&gt;The &amp;ldquo;Compact&amp;rdquo; algorithm can improve the speed when re-allocate memory ,if the new object in the heap allocated are compact, then the cache performance will be improved, because objects who was allocated together are often used together (the program locality principle), Therefore, a continuous space for the program is very important.&lt;/p&gt;&lt;p&gt;我是李鸣(Aicken) 请您继续关注我的下一篇文章。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/isline/aggbug/2013671.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/isline/archive/2011/04/12/2013671.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/isline/archive/2010/11/05/1869927.html</id><title type="text">物以类聚，人以群分：晒晒与腾讯站在一起的企业们</title><summary type="text">国内五家著名互联网企业，金山、搜狗、傲游、可牛、百度今早联手举行发布会，表示将选择不兼容360系列软件。那么这五家“知名”的互联网公司又是什么样的公司呢？就让我们来回忆一下吧。 金山：嗯，业界挺有名的，不过最拿得出手的不是什么“毒霸”，而是应该是游戏，单机版剑侠系列游戏可在国内大陆地区首屈一指，网游剑侠系列就不怎么样了，简直是一个装备买卖系统，玩家只...</summary><published>2010-11-05T06:34:00Z</published><updated>2010-11-05T06:34:00Z</updated><author><name>Aicken(李鸣)</name><uri>http://www.cnblogs.com/isline/</uri></author><link rel="alternate" href="http://www.cnblogs.com/isline/archive/2010/11/05/1869927.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/isline/archive/2010/11/05/1869927.html"/><content type="html">&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 国内五家著名互联网企业，金山、搜狗、傲游、可牛、百度今早联手举行发布会，表示将选择不兼容360系列软件。那么这五家&amp;ldquo;知&lt;/p&gt;&lt;p&gt;名&amp;rdquo;的互联网公司又是什么样的公司呢？就让我们来回忆一下吧。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 金山：嗯，业界挺有名的，不过最拿得出手的不是什么&amp;ldquo;毒霸&amp;rdquo;，而是应该是游戏，单机版剑侠系列游戏可在国内大陆地区首屈一&lt;/p&gt;&lt;p&gt;指，网游剑侠系列就不怎么样了，简直是一个装备买卖系统，玩家只靠钱就能有装备和等级，而且后来官方竟然提供白驹丸这样的&lt;/p&gt;&lt;p&gt;挂机道具，这和外挂有何区别呢？&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 再说说金山毒霸，刚推出时，竟然查不出冰河服务端，这个连知名木马都放过的玩意，还有脸出来对别的产品说三道四？&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 搜狗：互联网里流传着这样一句话，没上网的都知道搜狐，上网的都不去搜狐。呵呵这是由一定道理的，张Sir影视歌网四栖明星多&lt;/p&gt;&lt;p&gt;多少少拿网联网当娱乐做。再说搜狗，做的不错，但可有可无，Google输入比你也不差！&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 遨游：一家失败的软件公司，别糟蹋遨游的名字了。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 百度：为建立河蟹圈始终不懈奋斗，不惜挥刀阉割掉那个谁不希望网民知道的信息，试问你李彦宏，为一己私利你把用户知情权与&lt;/p&gt;&lt;p&gt;事实本真放在哪里？&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 还有百度那个臭名昭著的竞价排名，只要给钱你百度就大肆认为修改搜索结果，将大量假冒劣质信息排在首位，你可真便宜啊，给&lt;/p&gt;&lt;p&gt;钱就能&amp;ldquo;上&amp;rdquo;啊！&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 百度工具栏，刚推出时你不也是和CNNIC一样，在用户不知情的情况下强行安装无法彻底卸载吗！不过你就是点背，百度工具栏刚推&lt;/p&gt;&lt;p&gt;出不久360就出了卸载恶意软件的工具，想必你的非法利益受到很大的打击吧！&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 可牛：什么东西？点心吗？&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 腾讯：与上五家公司一样，一个被360触犯经济利益的公司，撕破脸皮般的不承认扫描用户硬盘数据的事实，打着维护用户利益为用&lt;/p&gt;&lt;p&gt;户着想的旗帜，卸载竞争对手的产品。物以类聚人以群分，与腾讯统一战线的都是些什么东西，腾讯会是什么东西呢？&lt;/p&gt;&lt;img src="http://www.cnblogs.com/isline/aggbug/1869927.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/isline/archive/2010/11/05/1869927.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/isline/archive/2010/08/31/1813722.html</id><title type="text">极限挑战—C#+ODP 100万条数据导入Oracle数据库仅用不到1秒</title><summary type="text">.Net程序中可以通过ODP调用特性，对Oracle数据库进行操作，今天来讲一下数据批量插入的功能，所用技术不高不深，相信很多朋友都接触过，小弟班门弄斧了，呵呵。这篇文章是上篇文章的续集，因为上一次试验的征集结果没有突破4秒的方法，所以这次继续挑战与挖掘新方法，虽然是Oracle，但仍具有一定收藏意义。 上一次文章中提及的试验： 极限挑战—C#100万条数据导入SQL SERVER数...</summary><published>2010-08-31T07:36:00Z</published><updated>2010-08-31T07:36:00Z</updated><author><name>Aicken(李鸣)</name><uri>http://www.cnblogs.com/isline/</uri></author><link rel="alternate" href="http://www.cnblogs.com/isline/archive/2010/08/31/1813722.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/isline/archive/2010/08/31/1813722.html"/><content type="html">&lt;p&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; .Net程序中可以通过ODP调用特性，对Oracle数据库进行操作，今天来讲一下数据批量插入的功能，所用技术不高不深，相信很多朋友都接触过，小弟班门弄斧了，呵呵。这篇文章是上篇文章的续集，因为上一次试验的征集结果没有突破4秒的方法，所以这次继续挑战与挖掘新方法，虽然是Oracle，但仍具有一定收藏意义。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 上一次文章中提及的试验： &lt;/p&gt;&lt;p&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href="http://www.cnblogs.com/isline/archive/2010/03/18/1688783.html"&gt;极限挑战&amp;mdash;C#100万条数据导入SQL SERVER数据库仅用4秒 (附源码)&lt;/a&gt;&lt;/b&gt; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href="http://www.cnblogs.com/isline/archive/2010/03/18/1688783.html"&gt;http://www.cnblogs.com/isline/archive/2010/03/18/1688783.html&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 这个试验是针对SQL SERVER数据库的，宿主环境也是.Net，有兴趣的朋友可以将这两个试验对比一下，为日后工作批量导数提供支持。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 另外，一些朋友对上次试验环境有些异议，认为应该对数据库和服务器做优化或设置，以体现试验最终的时间结果。这个固然会影响试验的时间结果，但考虑到在试验环境中，对数据库优化的标准与优化程度不便统一与定量，试验结果也不易说明其影响源，所以这次试验依然以标准数据库建库后的配置为主，试验所在服务器硬件环境与上次试验保持一致。实验目的在于挖掘、对比宿主程序中的数据批量操作方法。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 有新方法提升性能时间指标的朋友，欢迎互相切磋，互相提高，嘴上功夫就免了。。。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 好了正文开始。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="font-size: 14pt;"&gt;● 普通肉垫式 &lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 什么叫批量插入呢，就是一次性插入一批数据，我们可以把这批数据理解为一个大的数组，而这些全部只通过一个SQL来实现，而在传统方式下，需要调用很多次的SQL才可以完成，这就是著名的&amp;ldquo;数组绑定&amp;rdquo;的功能。我们先来看一下传统方式下，插入多行记录的操作方式： &lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div onclick="cnblogs_code_show('8c508a7f-056b-48d4-9f4c-c193cdf59521')" style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" class="code_img_closed" id="code_img_closed_8c508a7f-056b-48d4-9f4c-c193cdf59521" style="display: none;" /&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" onclick="cnblogs_code_hide('8c508a7f-056b-48d4-9f4c-c193cdf59521',event)" class="code_img_opened" id="code_img_opened_8c508a7f-056b-48d4-9f4c-c193cdf59521" /&gt;&lt;div id="cnblogs_code_open_8c508a7f-056b-48d4-9f4c-c193cdf59521"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;设置一个数据库的连接串， &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; connectStr &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;User Id=scott;Password=tiger;Data Source=&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;br /&gt;&lt;br /&gt;OracleConnection conn &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; OracleConnection(connectStr); &lt;br /&gt;&lt;br /&gt;OracleCommand command &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; OracleCommand(); &lt;br /&gt;&lt;br /&gt;command.Connection &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; conn; &lt;br /&gt;&lt;br /&gt;conn.Open(); &lt;br /&gt;&lt;br /&gt;Stopwatch sw &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Stopwatch(); &lt;br /&gt;&lt;br /&gt;sw.Start(); &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;通过循环写入大量的数据，这种方法显然是肉垫 &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; recc; i&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;br /&gt;&lt;br /&gt;{ &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; sql &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;insert into dept values(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; i.ToString() &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;,&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; i.ToString() &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;,&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; i.ToString() &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;)&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;br /&gt;&lt;br /&gt;command.CommandText &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; sql; &lt;br /&gt;&lt;br /&gt;command.ExecuteNonQuery(); &lt;br /&gt;&lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;sw.Stop(); &lt;br /&gt;&lt;br /&gt;System.Diagnostics.Debug.WriteLine(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;普通插入:&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; recc.ToString() &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;所占时间:&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; sw.ElapsedMilliseconds.ToString()); &lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 我们先准备好程序，但是先不做时间的测定，因为在后面我们会用多次循环的方式来计算所占用的时间。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;strong&gt;&lt;span style="font-size: 14pt;"&gt; ● 使用ODP特性 &lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 看上面的程序，大家都很熟悉，因为它没有用到任何ODP的特性，而紧接着我们就要来介绍一个神奇的程序了，我们看一下代码，为了更直观，我把所有的注释及说明直接写在代码里： &lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div onclick="cnblogs_code_show('b457e208-1cc0-4d23-b12c-d8d944ca601b')" style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" class="code_img_closed" id="code_img_closed_b457e208-1cc0-4d23-b12c-d8d944ca601b" /&gt;&lt;img src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" onclick="cnblogs_code_hide('b457e208-1cc0-4d23-b12c-d8d944ca601b',event)" class="code_img_opened" id="code_img_opened_b457e208-1cc0-4d23-b12c-d8d944ca601b" style="display: none;" /&gt;&lt;div class="cnblogs_code_hide" id="cnblogs_code_open_b457e208-1cc0-4d23-b12c-d8d944ca601b"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;设置一个数据库的连接串 &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; connectStr &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;User Id=scott;Password=tiger;Data Source=&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;br /&gt;&lt;br /&gt;OracleConnection conn &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; OracleConnection(connectStr); &lt;br /&gt;&lt;br /&gt;OracleCommand command &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; OracleCommand(); &lt;br /&gt;&lt;br /&gt;command.Connection &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; conn; &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;到此为止，还都是我们熟悉的代码，下面就要开始喽 &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;这个参数需要指定每次批插入的记录数 &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;command.ArrayBindCount &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; recc; &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;在这个命令行中,用到了参数,参数我们很熟悉,但是这个参数在传值的时候 &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;用到的是数组,而不是单个的值,这就是它独特的地方 &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;command.CommandText &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;insert into dept values(:deptno, :deptname, :loc)&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;br /&gt;&lt;br /&gt;conn.Open(); &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;下面定义几个数组,分别表示三个字段,数组的长度由参数直接给出 &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] deptNo &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;[recc]; &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] dname &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;[recc]; &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] loc &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;[recc]; &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 为了传递参数,不可避免的要使用参数,下面会连续定义三个 &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 从名称可以直接看出每个参数的含义,不在每个解释了 &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;OracleParameter deptNoParam &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; OracleParameter(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;deptno&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;br /&gt;&lt;br /&gt;OracleDbType.Int32); &lt;br /&gt;&lt;br /&gt;deptNoParam.Direction &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; ParameterDirection.Input; &lt;br /&gt;&lt;br /&gt;deptNoParam.Value &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; deptNo; &lt;br /&gt;&lt;br /&gt;command.Parameters.Add(deptNoParam); &lt;br /&gt;&lt;br /&gt;OracleParameter deptNameParam &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; OracleParameter(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;deptname&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;br /&gt;&lt;br /&gt;OracleDbType.Varchar2); &lt;br /&gt;&lt;br /&gt;deptNameParam.Direction &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; ParameterDirection.Input; &lt;br /&gt;&lt;br /&gt;deptNameParam.Value &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; dname; &lt;br /&gt;&lt;br /&gt;command.Parameters.Add(deptNameParam); &lt;br /&gt;&lt;br /&gt;OracleParameter deptLocParam &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; OracleParameter(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;loc&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, &lt;br /&gt;&lt;br /&gt;OracleDbType.Varchar2); &lt;br /&gt;&lt;br /&gt;deptLocParam.Direction &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; ParameterDirection.Input; &lt;br /&gt;&lt;br /&gt;deptLocParam.Value &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; loc; &lt;br /&gt;&lt;br /&gt;command.Parameters.Add(deptLocParam); &lt;br /&gt;&lt;br /&gt;Stopwatch sw &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Stopwatch(); &lt;br /&gt;&lt;br /&gt;sw.Start(); &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;在下面的循环中,先把数组定义好,而不是像上面那样直接生成SQL &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; recc; i&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;br /&gt;&lt;br /&gt;{ &lt;br /&gt;&lt;br /&gt;deptNo[i] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; i; &lt;br /&gt;&lt;br /&gt;dname[i] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; i.ToString(); &lt;br /&gt;&lt;br /&gt;loc[i] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; i.ToString(); &lt;br /&gt;&lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;这个调用将把参数数组传进SQL,同时写入数据库 &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;command.ExecuteNonQuery(); &lt;br /&gt;&lt;br /&gt;sw.Stop(); &lt;br /&gt;&lt;br /&gt;System.Diagnostics.Debug.WriteLine(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;批量插入:&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; recc.ToString() &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;所占时间:&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt;sw.ElapsedMilliseconds.ToString()); &lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 以上代码略显冗长，但是加上注释后基本也就表达清楚了。 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 好了，到目前为止，两种方式的插入操作程序已经完成，就剩下对比了。我在主函数处写了一个小函数，循环多次对两个方法进行调用，并且同时记录下时间，对比函数如下： &lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;50&lt;/span&gt;&lt;span style="color: #000000;"&gt;; i&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;br /&gt;&lt;br /&gt;{ &lt;br /&gt;&lt;br /&gt;Truncate(); &lt;br /&gt;&lt;br /&gt;OrdinaryInsert(i &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1000&lt;/span&gt;&lt;span style="color: #000000;"&gt;); &lt;br /&gt;&lt;br /&gt;Truncate(); &lt;br /&gt;&lt;br /&gt;BatchInsert(i &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1000&lt;/span&gt;&lt;span style="color: #000000;"&gt;); &lt;br /&gt;&lt;br /&gt;} &lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 当数据量达到100万级别时，所用时间依然令人满意，最快一次达到890毫秒，一般为1秒左右。 &lt;/p&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 经过试验，得出一组数据，可以看出两种方式在效率方面惊人的差距（占用时间的单位为毫秒），部分数据如下：&lt;/div&gt;&lt;div align="center"&gt;&lt;table align="center" cellpadding="0" cellspacing="0" border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="92"&gt;&lt;p&gt;记录数&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;标准&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;批处理&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="92"&gt;&lt;p&gt;1000&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;1545&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;29&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="92"&gt;&lt;p&gt;2000&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;3514&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;20&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="92"&gt;&lt;p&gt;3000&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;3749&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;113&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="92"&gt;&lt;p&gt;4000&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;5737&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;40&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="92"&gt;&lt;p&gt;5000&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;6820&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;52&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="92"&gt;&lt;p&gt;6000&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;9469&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;72&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="92"&gt;&lt;p&gt;7000&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;10226&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;69&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="92"&gt;&lt;p&gt;8000&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;15280&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;123&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="92"&gt;&lt;p&gt;9000&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;11475&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;83&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="92"&gt;&lt;p&gt;10000&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;14536&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;121&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="92"&gt;&lt;p&gt;11000&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;15705&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;130&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="92"&gt;&lt;p&gt;12000&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;16548&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;145&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="92"&gt;&lt;p&gt;13000&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;18765&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;125&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="92"&gt;&lt;p&gt;14000&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;20393&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;116&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="92"&gt;&lt;p&gt;15000&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;22181&lt;/p&gt;&lt;/td&gt;&lt;td width="66"&gt;&lt;p&gt;159&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;div align="center"&gt;&amp;nbsp;&lt;/div&gt;&lt;div align="left"&gt;因为篇幅原因，不再粘贴全部的数据，但是我们可以看一下由此数据生成的散点图：&lt;/div&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/isline/WindowsLiveWriter/CODP100Oracle1_DB57/clip_image002_2.gif"&gt;&lt;img height="257" width="444" src="http://images.cnblogs.com/cnblogs_com/isline/WindowsLiveWriter/CODP100Oracle1_DB57/clip_image002_thumb.gif" alt="clip_image002" border="0" title="clip_image002" style="display: block; float: none; margin-left: auto; margin-right: auto; border: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/isline/WindowsLiveWriter/CODP100Oracle1_DB57/clip_image002_2.gif"&gt;&lt;/a&gt;&amp;nbsp; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 其中有些数据有些跳跃，可能和数据库本身有关系，但是大部分数据已经能说明问题了。看了这些数据后，是不是有些心动了？ &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 源程序放了一段时间直接拷贝贴过来了，可能需要调试一下才能跑通，不过不是本质性问题，对了如果要测试别忘记安装Oracle访问组件。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/isline/aggbug/1813722.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/isline/archive/2010/08/31/1813722.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
