<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blog.darkthread.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>黑暗執行緒 : Tips, Performance</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Tips/Performance/default.aspx</link><description>Tags: Tips, Performance</description><dc:language>zh-CHT</dc:language><generator>CommunityServer 2007.1 (Debug Build: 20917.1142)</generator><item><title>Smart C# Compiler</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2008/01/09/smart-compiler.aspx</link><pubDate>Tue, 08 Jan 2008 21:58:01 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:1498</guid><dc:creator>Jeffrey</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=1498</wfw:commentRss><comments>http://blog.darkthread.net/blogs/darkthreadtw/archive/2008/01/09/smart-compiler.aspx#comments</comments><description>&lt;p&gt;&lt;span id="PostName"&gt;&lt;/span&gt;前陣子幫同事追查問題，由於懷疑主機上的程式版本有誤，便找來Source Code，與Reflector反編譯(Decompile)主機上DLL得到的Code比較，在一段程式上發現了小小的差異: Souce Code裡是先將DropDownList的SelectedValue先存到變數中，再將該變數當成呼叫另一個函數的參數；而Reflector中看到的卻是直接將DropDownList.SelectedValue直接被當成呼叫另一函數的參數。&lt;/p&gt; &lt;p&gt;程式寫法的差異，讓人懷疑上線的程式版本有誤。但同事印象中從頭到尾不曾用過這種寫法，追查上線記錄則顯示版本管理出錯的機率極低，到底是怎麼一回事? 幾經波折，最後在其他地方找到錯誤的根源，與程式邏輯無關，證實了程式版本並沒有任何問題。但引發一個有趣的結論: &amp;quot;DLL反編譯的結果與Source Code可能存在差異&amp;quot;，之前在探討&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2007/05/29/kb-nullable-value-type-varname-null.aspx" target="_blank"&gt;Nullable Value Type&lt;/a&gt;時，曾有類似的經驗，莫非這次又遇到?&lt;/p&gt; &lt;p&gt;一些效能討論文章中提過Compiler本身會做一些最佳化，剛才提到Source Code將DropDownList.SelectedValue存成變數，變數只被用了一次--當成呼叫函數時的參數。少了這個變數不會對邏輯有任何影響，還可以省下宣告/建立變數的成本，的確是種最佳化。&lt;/p&gt; &lt;p&gt;為了印證這點，我寫了以下的程式，還順道驗證一下上回提過的&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2007/12/15/stringbuilder-for-static-string-concate.aspx" target="_blank"&gt;靜態字串相加會直接被Compiler做掉&lt;/a&gt;的理論，程式如下: &lt;/p&gt; &lt;div class="BlogCodeBlock"&gt; &lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Text;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; SmartCompiler&lt;/pre&gt;&lt;pre&gt;{&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;class&lt;/span&gt; Program&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args)&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;int&lt;/span&gt; j = 0;&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;string&lt;/span&gt; s = &lt;span class="str"&gt;&amp;quot;Hello &amp;quot;&lt;/span&gt; + &lt;span class="str"&gt;&amp;quot;World!&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;string&lt;/span&gt; t = s;&lt;/pre&gt;&lt;pre&gt;            Console.Write(t);&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;int&lt;/span&gt; i = 3 + 5;&lt;/pre&gt;&lt;pre&gt;            Console.Write(i);&lt;/pre&gt;&lt;pre class="alt"&gt;        }&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;pre class="alt"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;用Reflector解析一下，有幾個地方被&amp;quot;最佳化&amp;quot;了:&lt;/p&gt;
&lt;p&gt;1.變數j宣告了卻從未用到，Compiler直接忽略，在DLL中完全未現身。&lt;br /&gt;2.由於s只被用來指定給t，所以就直接用t取代s。&lt;br /&gt;3.&amp;quot;Hello World!&amp;quot;直接變成一個字串指定給t。&lt;br /&gt;4.Compiler直接算好3+5=8指定給i。&lt;/p&gt;
&lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/1471/original.aspx" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Compiler真是愈來愈聰明了，不過不代表以後程式可以亂寫，再交給Compiler去調。Compiler能做的小修正有限，省下來多半只是幾個Tick的極微時間，有時數百萬個Compiler最佳化也抵不上Coding時的一個小疏忽，只能當成錦上添花。&lt;/p&gt;
&lt;p&gt;講到Coding時應注意效能，最近又再度見識到在上萬次迴圈中反覆做Database查詢的&amp;quot;好&amp;quot;程式，一整個囧!&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=1498" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Tips/default.aspx">Tips</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Performance/default.aspx">Performance</category></item><item><title>KB-Rapid-Fail Protection of IIS 6</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2007/07/20/kb-rapid-fail-protection-of-iis-6.aspx</link><pubDate>Thu, 19 Jul 2007 20:04:43 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:915</guid><dc:creator>Jeffrey</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.darkthread.net/blogs/darkthreadtw/rsscomments.aspx?PostID=915</wfw:commentRss><comments>http://blog.darkthread.net/blogs/darkthreadtw/archive/2007/07/20/kb-rapid-fail-protection-of-iis-6.aspx#comments</comments><description>&lt;p&gt;對一台IIS 6進行壓力測試時，因壓力過大Web不支倒地，接著再連上Web，出現的都是HTTP 503 Service Unavailable。 &lt;p&gt;查看Event可以看到5個接連的W3SVC Warning及一個W3SVC Error。 &lt;p&gt;Warning Event 1011 from W3SVC 共有四個 &lt;p&gt;&lt;font color="#ff8000"&gt;伺服應用程式集區 'DefaultAppPool' 的處理序與 World Wide Web Publishing 服務通訊時發生嚴重錯誤。處理序識別碼為 '3808'。資料欄位含有錯誤號碼。 &lt;br&gt;A process serving application pool ApplicationPool suffered a fatal communication error with the World Wide Web Publishing Service. The process id was '3808'.&lt;/font&gt; &lt;p&gt;接著是Error Event 1002 from W3SVC  &lt;p&gt;&lt;font color="#ff8000"&gt;正在自動停止應用程式集區 'DefaultAppPool'，因為在伺服該應用程式集區的處理序中發生許多失敗。&lt;br&gt;Application pool 'DefaultAppPool' is being automatically disabled due to a series of failures in the process(es) serving that application pool.&lt;/font&gt;&lt;/p&gt; &lt;p&gt;同事&lt;a href="http://blog.xuite.net/mingche_tw/photo"&gt;小熊子&lt;/a&gt;分享了他的經驗，原來這是IIS6所謂的&lt;a href="http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/5a6d38da-37d8-4d56-b6bd-1a2cbca59a57.mspx?mfr=true"&gt;Rapid Fail Protection&lt;/a&gt;保護機制。當IIS因為程式不良或遭到惡意攻擊時，造成Worker Process Crash，IIS會自動重啟一個新的Worker Process繼續提供服務；但如果新啟動的Worker Process接連Crash，IIS就會停用該Application Pool，以免持續不斷重啟新Worker Process的沈重負擔把Server搞掛(&lt;a href="http://blogs.iis.net/thomad/archive/2007/01/16/tricking-rapid-fail-protection.aspx"&gt;參考&lt;/a&gt;)。&lt;/p&gt; &lt;p&gt;預設值是5分鐘內發生5次異常就會觸發Rapid Fail Protection，這就是為什麼在事件簿中看到5個Warning+1個Error的理由。Rapid-Fail Protection的設定UI如下:&lt;/p&gt; &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/914/original.aspx"&gt;&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=915" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Tips/default.aspx">Tips</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Trouble-Shooting/default.aspx">Trouble-Shooting</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Performance/default.aspx">Performance</category></item></channel></rss>