2010年1月11日星期一

比較ConcurrentDictionary和一些同步元件的效能

 

.Net 4.0出了不少跟多工有關係的新類別,其中ConcurrentDictionary對我來說還挺實用的. 至少不用再寫一堆EnterLock, 程式會好看很多. 但是在實際使用前,有鑑於之前遇到Array.Sort效率低落的經驗, 還是先測試一下基本效率好了

程式很簡單,就只是用迴圈,測寫入跟讀取十萬次

結果大如下,不過請注意這只是單執行序迴圈,這不代表實際多執行序情況運用的效能,只是給大家當個參考

測試環境為Win7, Visual Studio 2010 Beta2, Single Thread

結果如下,時間單位是ms

Dictionary with ReaderWriterLock Writing Time:51.3122
Dictionary with ReaderWriterLock Reading Time:29.9333
Dictionary with ReaderWriterLockSlim Writing Time:29.4264
Dictionary with ReaderWriterLockSlim Reading Time:18.2223


Dictionary Writing Time:31.1934
Dictionary Reading Time:4.9508
Dictionary with try-finally Writing Time:17.6937
Dictionary with try-finally Reading Time:6.068


Dictionary with Mutex Writing Time:210.7196
Dictionary with Mutex Reading Time:209.661
Dictionary with Semaphore Writing Time:243.5548
Dictionary with Semaphore Reading Time:207.5424
Dictionary with SemaphoreSlim Writing Time:63.7131
Dictionary with SemaphoreSlim Reading Time:52.0932
Dictionary with lock Writing Time:21.5253
Dictionary with lock Reading Time:9.7504


ConcurrentDictionary Writing Time:50.1722
ConcurrentDictionary Reading Time:10.9998
ConcurrentDictionary with try-finally Writing Time:60.7422
ConcurrentDictionary with try-finally Reading Time:9.3537

結論:

從頭開始看, ReaderWriterLockSlim的確比ReaderWriterLock快, 此時看一下單純存取Dictionary的效率…見鬼了,寫入部分有使用ReaderWriterLockSlim比什麼都沒做更快. 後來測試一個加了try-finally的版本,的確會比較快…可能跟.Net內部機制有關係吧,管他的.

再來看到老牌的Mutex和Semaphore, 相較之下除了慢到靠背以外我沒有別的評語, 看來以後程式最佳化時要把這兩傢伙開除了. SemaphoreSlim表現倒是還可以.

既然Mutex測了,那Moniter也來一下好了. lock好像是用Monitor實作的, 測試結果是比Mutex好多了.

最後當然是測試主角ConcurrentDictionary, 寫入稍慢, 讀取到還挺快的. 由於剛剛測出Dictionary有曖昧關係, ConcurrentDictionary順便測一下的結果倒是還正常.

隨便測測, 有空還要玩玩Parallelism的東西, 到時在來報告經驗吧


2009年8月1日星期六

愛,在哪裡?

一同走過了這麼多個年頭

許多美好與歡樂,一直烙印在我的心中

走著走著,雖然不太崎嶇,也沒有偶像劇那般刻苦銘心的劇情

但是我在的心中,妳一直是我最珍貴的寶物

 

也許是太過平順,也許沒有太多哀傷

彷彿如糖似蜜,卻又像白開水一般

這麼近,卻又那麼遠

 

我承認,我並沒有年少輕狂時的那股浪漫

我不會在情人節的時候,準備一個最完美的驚喜

我不記得我們在一起的紀念日(雖然妳也不記得

我想給妳最完美的生活,但卻只給了妳一無所有

我的心,宛如鐵石般的麻木不仁

 

我是真的愛妳

即使我經常挑剔妳不夠積極

也許妳覺得我的稱讚只是敷衍

抱歉我的眼殘只看得到妳的美

我那凌亂的出身讓我不甘於平凡

卻只得拖著妳與我一起狂奔

沒得讓妳仔細欣賞沿路的美景

一切只是為了

我要給妳不平凡的未來

 

但是

我感到非常的疲憊

走在妳的身旁

我不知道妳心中是否有我

一同生活

卻活在兩個世界

我逞強的表面

已經脆弱的不知該至身何處

 

我的夢想

是希望能夠帶著妳去世界各地旅行

妳看那歐洲充滿藝術的美景

妳不曾感受過義大利的熱情

我想與妳

坐在愛情海的沙灘

細數著浪潮的聲音

我想與妳

在瑞士那堆滿雪的山頭

看看到底能算出幾顆星星

我想帶妳去舊金山那可以俯瞰整個城市的橋上

我想帶妳去我未曾探索的各個角落

 

可是

愛,在哪裡?

妳彷彿不願多看我一眼

我在妳的心中

是不是比不上一個小天

我說的每一句話

是那樣的無趣

讓妳寧願躲進可愛的雜誌裡

我,到底在哪裡?

 

最近,我沒有為了妳去鍛鍊體魄

我沒有去中醫那邊好好的調養身體

我也沒有陪妳騎著腳踏車去看美麗的夕陽

即使是為了能讓妳在35歲後就可以享受人生

但仍然是我的罪過

也許我帶妳買了幾件衣服

也許我也稱讚了妳的美麗

也許我沉醉於妳那婀娜多姿的舞步

但是妳不知道我愛你,不是嗎

 

我說了太多了

就算妳不相信好了

我也是有害羞的時候

我沒有辦法告訴妳

我需要妳對我關懷

我需要妳對我體貼

我需要妳融化我那快要封閉的心

我不知道妳在不在意

我只能當作妳不明白我的心意

 

很抱歉我提出如此奢侈的需求

我要看得到妳的愛

我不要每天你我距離不到兩公尺

心卻隔著一片海

我的愛

只希望妳明白


2009年7月25日星期六

IronPython+C# under Visual Studio 2010 – Setup search path before loading script

Previous article shows how to debug C#+Ironpython. In this article, I will show you how to setup search path before loading python files.




Here is an example:




var path = Application.StartupPath;
var searchPath = ".;your\path"; //Setup you path here

Dictionary<string, object> options = new Dictionary<string, object>();
options["SearchPaths"] = searchPath;

ScriptRuntime py = Python.CreateRuntime(options);




Why I wrote this article in English? Because my English writing is poor, and this is a chance to practice. In the other hand, I can help more people by using English.



程式語言的新進化:C#+IronPython,附贈在Visual Studio 2010下debug C#+IronPython的方式

python-debug-conver

本篇為技術文件,一般人士勿進!
如果你真的得看,那你如果不是很有興趣,就是很倒楣。

使用食材:

  • Visual Studio 2010 beta2
  • IronPython 2.6 beta1 for .Net 4.0




使用.Net Framework有一個很大的好處,就是可以方便的同時使用不同的語言,來完成不同部份的工作。
例如瘋貓以前對C++比較熟,在需要作某些跟Windows API的互動或者想呼叫以前C++寫的Code,我就可以使用C++.Net來寫一個函式庫給C#呼叫。

很可惜的是,應用大概也只有這樣了。因為在一個程式裡,沒事作成許多不同程式語言,只是給自己找麻煩,而且會讓維護的人很想砍你(即使是你自己維護…)。

但是有一種例外情況,就是當兩種語言特性差很多的時候。

利用一個高階的腳本語言來撰寫程式中某些邏輯,使其不要跟程式本身的運作邏輯整個黏死在一起。這是一個很常見的作法,例如一些遊戲的AI會透過lua等腳本語言撰寫(線上遊戲魔獸世界的UI擴充介面、RO的傭兵和人工生命AI,都是用這種作法)。

除了隔離的效果,當然也有簡化的意思。畢竟像是C#/C++/Java這種程式,寫起來總是比Python/Ruby/Lua等腳本語言來的複雜的多,光是要定義一堆class,就足以讓非專業人士難以學習和撰寫。

在最新的Visual Studio 2010裡,強化了C#以及IronPython之間的結合性。如何使用我不多介紹,這點大家自己去找範例就好了。這裡要講的是一個非常重要的東西,如何在VS環境中同時對C#和IronPython進行debug

當你跟著IronPython內建的範例作好了.Net 4.0下的C#呼叫IronPython的簡單範例後,其實是無法對IronPython進行debug的。不管你對呼叫的那一行按F10還是F11,都是直接把Python的部份執行完畢。IronPython內雖然有一個debug的教學,可惜那個東西只能單獨debug Python程式,對於C#內呼叫IronPython的整合沒有幫助。

那到底要如何對IronPython的Script進行debug呢?請見下圖內的程式碼,其實只要在建立ScriptRuntime的時候傳一點參數,也就是 Debug = true,這樣你就可以在python的script中自由下斷點了,很簡單吧。

python-debug1

簡單個屁!這個玩意兒完全沒有說明文件,舊版本的debug模式也不是這樣設定,這可是瘋貓跑去翻IronPython的source code翻了半天,嘔心瀝血才發現的耶!你竟然跟我說簡單!

呼…冷靜,冷靜。正所謂沒圖沒真相,再補上一張debug python的圖。各位可以看到,在watch裡面也可以看python的變數哦,還不錯吧。從此以後用一套系統就可以直接進行主程式跟腳本的debug,這時在是太美妙了阿。

python-debug2

雖然瘋貓懷疑寫這種東西到底能夠對幾個人有幫助,希望能夠多幫助到對寫程式懷有熱血的人囉,歡迎來交個朋友。



2009年7月16日星期四

投資是計畫,不是過程

瘋貓很久沒寫文章了,難得今天一時興起,來聊聊最近看的一些書好了。

這幾天K最多的書呢,就是窮爸爸富爸爸系列的書。我想這一系列的書很多人都看過了,對於其中所提的很多觀念,可能很多人都會感到非常的遙遠吧。

瘋貓本身是屬於書上S象限那一類的人,也就是專業工作者。之前也曾經在沒有作很多準備工作的情況下,一頭想要跳進I象限當個專業投資人。不過實際上的情況呢,就像是書上說得那種有勇無謀的投機者罷了。





投資是一個充滿刺激的領域,他無時無刻都在吸引更多人跳入這個滿是誘惑的圈子裡。但是在無知的情況下,這個地方已經不能用風險來形容,根本就是危機四伏,一點贏的機會都沒有

經歷了幾個月的瘋狂,也繳了幾十萬的學費,瘋貓曾經一度逃避這充滿挫敗的領域。而經歷了一年多的修養,也是該好好反省的時候了。失敗的原因當然有無數種,包跨了

  • 無知
  • 沒有風險概念
  • 沒有情緒控管概念
  • 毫無紀律
  • 沒有明確的進出場策略
  • 貪得無厭
  • 最重要的一點,沒有目標

當時我做的事是非常瘋狂的,再沒有任何專業判斷能力的情況下,竟然妄想靠著一些簡單的技術分析,就想要在這片血海廝殺。這簡直就像是沒有受過訓練的人,去參加重量級拳擊賽一樣。這裡面不會有幸運,就算你打到了對方一拳,最終你也將體無完膚得出場。

回到正題,在拜讀了富爸爸系列的書籍之後,其中有提到一點:投資是計畫,而不是過程

這件想法著實讓我思考了一陣子。一次投資的過程包含了買進、賣出,可能讓你獲利10%。然後接著呢?拿這110%的資金繼續投資?不斷反覆?像是這樣的問題,我著實沒有認真的去思考過。

所謂的計畫,必須先知道自己的目標。目標是最基本的,至少你得知道你想在多少時間內達到什麼樣的成就。否則即時你有很專業的投資知識,也只會像瘋貓當初一樣,貪得無厭,最後落得一場空罷了。

接著得衡量自己的投資能力、財務狀態、願意花費的時間、願意承受的風險等諸多因素。你會慢慢瞭解在什麼階段,你應該使用什麼樣的工具作投資。

瘋貓擁有很成功的"失敗經驗",這段日子裡,大多人會犯的錯誤,我可是一個都沒有錯過。有機會瘋貓會盡量與大家分享這段經驗,但這邊最重要的一點是,先從計畫開始。即使你很心急,想略過一切先跳下去讓人打幾巴掌,也請先規劃好資金,並且把這列入計畫的一部分吧。



2009年4月23日星期四

我X!C# SortedDictionaray排序效率…

又是該死的程式筆記文,閒人勿近

臨時想記一點心得,可是不知道要記在哪邊,只好先寫在Blog了
(囧r2…

看來以後這邊會淪為放程式筆記的地方?

這兩天在最佳化一個A*路徑演算法的效率。程式裡面有個地方用到了排序。原本的程式是土法煉鋼自己寫BinarySearch來作插入,來達成資料新增時直接排序的效果。





但是.Net FrameWork不是也有提供SortedDictionary來達成一樣的功能嗎?既然是系統函式庫,效能應該會不錯吧。經過了一番實驗....效能果然是…降低了非常的多(這邊的Sorting Key是自然的int型態)。看來可能是因為SortedDictionary的compare是使用ICompare<T>的關係,除了多一層呼叫以外,更對key進行了該死的boxing和unboxing等耗時的行為。(也可能是取值時使用iterator的關係…who cares?反正很爛)

(看不懂沒關係,只要知道其實SortedDictionary對於自然型態的key效率很爛就行了)

那至於SortedList呢?文件上寫插入(羞 …的耗時為O(n),我想應該連考慮都不用了。

此時的瘋貓,懷念起以前C++時代的STL函式庫,有著超高效能及各種強大功能的container …對了,那怎不使用C++來完成這段Code呢?有著瘋狂實驗精神的瘋貓立刻又用了一個manged C++包裝unmanaged C++的library…(包肉粽?)使用了multimap…效能測試後,還真是夠差的…怎麼會這樣@@?

查了一些資料之後,才發現managed code呼叫unmanaged code時,call及return都會有額外的overhead,而且還不小…看來這招式沒路用了。

最後,聽說微軟也有推出CLR版本的STL…姑且一試吧…快速報告結果:效.能.超.爛!既然都run在CLR下了,我竟然還期待他的效能,看來我真的病的不輕!

最後,這段Code一行都沒改,就是最高效能。結論就是,要達到高的效能,還是得針對自己的case去寫演算法,不能倚靠系統提供的函式庫。作效能系統最佳化的程式設計師還有很長的一段苦日子得走…(系統自動選字還選成”程式設計師屍骸”= =)

順道一提,這種低階最佳化只能增加很少的效能,有個30~50%就很好了。要真的作到倍數以上的提昇,必須從演算法設計上下手。該演算法重新設計後,效能提昇了約3倍多,之前為了那30%忙半天真是忙辛酸的…



2009年4月14日星期二

Google App Engine/Java 一堆問題初體驗

嗯,很久沒來更新,一更新就是個乏味的技術文件…管他的。

最近Google App Engine很轟動的推出了Java Servlet版,當然是問題一堆的早期體驗版。從來沒有玩過Java的瘋貓,自然想利用這個機會好好的體驗一番囉。

對細節有興趣的自己去Google App Engine網站看一下,瘋貓先作個小小簡介。



  1. 支援標準Servlet,但別高興太早,問題應該是一堆
  2. 實做JVM,所以不只有Java,理論上跑JVM的語言都可以。例如Groovy,PHP,目前還看到了Jython(那麼愛Python,直接用Python版不就好了ˊˋ)。
  3. 資料庫採用JDO介面,但是底子是用Google DataStore。意思就是沒有join,where的功能幾乎都得自己實做。要有效率的使用還是得研究Google DataStore。
  4. 能直接跟Google Web Toolkit(又是一個沒有什麼人在用的東西!)整合,省去寫麻煩JavaScript的問題…多了要學新東西的問題…。
  5. 目前許多framework套上去聽說都有問題…討論區看到的
  6. 支援JSP
  7. 提供Eclipse的plugin,除了某些令人抓狂的bug外,大致上還不錯
  8. 跟Python版差不多的sandbox,沒有socket,沒有process和thread,沒有system call,檔案系統不能寫。

由於瘋貓跟Java很不熟,更別提Servlet了。不過總算還是把一些實驗品完成。底下稍微談談遇到的問題以及解決方案(很多錯誤的錯誤訊息又臭又長,請看仔細囉):

  1. 在Eclipse執行JSP檔發生找不到javac.exe
    解決:設定eclipse的JRE使用JDK而不是JRE
  2. 執行appcfg.cmd找不到javac.exe
  3. 新增參數到appcfg.cmd設定JDK路徑,如下

    @java -Djava.home="c:\Program Files\Java\jdk1.6.0_13\jre" -cp "%~dp0\..\lib\appengine-tools-api.jar" com.google.appengine.tools.admin.AppCfg %*

  4. UTF-8編碼的jsp無法正確在瀏覽器選擇其編碼
  5. JSP檔案加上
    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
  6. 無法上傳具有utf-8編碼的JSP檔(這問題搞我超久…Google以後應該會修正吧)
    這應該算是BUG吧。在Eclipse執行時,Google Plugin對於JSP產生的Java檔,compile時會加上-encoding UTF8,但是上傳時的compile卻不會。而且錯誤訊息只有Java檔編譯失敗…瘋貓解決的方式是把原本的javac.exe更名,並製作一個假的javac.exe程式(我是用C#寫),使其將參數加上-encoding UTF8,再呼叫真的javac.exe,並傳回javac.exe的回傳碼。如果是在Linux下的環境應該寫個script就行了。在Windows下真命苦…
  7. 刪除了war\WEB-INF\classes中的檔案,無法復原
  8. 將每個.java檔重新存檔,使eclipse的plugin自動重新compile,並且將src\META-INF自行複製過去

搞了一天,總算是能夠把UTF-8編碼的JSP弄到Server上跑了,希望對大家有幫助。

由此可知Google測試時應該只有針對英文,可憐了其他語系的開發者。不過他們的工程師哪故的到那麼多,應該也是瘋狂爆肝中吧…不過以他們的待遇,他們的肝…該爆…