月歸檔:八月 2008

用Benchmark測試不同ruby代碼的運行速度

如果比較功能相同的幾組代碼的運行速度, 可以使用ruby語言里的Benchmark模塊.
(開始前 設置中文環境, $KCODE = ‘u’)
比如, 連接兩個字串, 如:
str1 = "中國"
str2 = "一定強!!!"

可以使用+
?> str1 + str2
=> "中國一定強!!!"
也可使用
>> "#{str1}#{str2}"
=> "中國一定強!!!"
還可以使用<<
>> str1 << str2
=> "中國一定強!!!"
(注意這種方法會改變str1的值,
>> str1
=> "中國一定強!!!")

如果想要知道這三種方法哪一個速度更快, 就可以使用Benchmark比較.
先定義三個不同的方法:

def joined_by_plus(str_a, str_b)
    500000.times do; str_a.dup + str_b; end
end

def joined_by_uniting(str_a, str_b)
    500000.times do; "#{str_a.dup}#{str_b}"; end
end

def joined_by_adding(str_a, str_b)
    500000.times do; str_a.dup << str_b; end
end

因為這三種方法速度都很快, 比較一次的時間很難分出上下, 所以每種方法都做500000次.
因為<< 會改變變量, 所以在第三個方法中使用了str_a.dup, 備份出一個str_a來測試, 其它二個方法雖然從理論上不須要這個dup, 但為了時間上的公平, 也給它們加上了.

下面是測試代碼:
require ‘benchmark’

Benchmark.bmbm(10) do |t|
  t.report(‘加號連接’) { joined_by_plus(str1, str2) }
  t.report(‘放進引號’) { joined_by_uniting(str1, str2)}
  t.report(‘使用<<’) { joined_by_adding(str1, str2)}
end

bmbm是Benchmark的測試方法, 這是雙重測試, 用來提高精確度. 裡面參數10用來調節標籤在結果里的顯示佔位寬度, 不對結果產生影響.
report(‘加號連接’)里的參數是為相應測試的標籤名, 用來區別測試結果.

下面就是結果:

Rehearsal ————————————————
加號連接   1.800000   0.580000   2.380000 (  2.435614)
放進引號   2.080000   0.590000   2.670000 (  2.706669)
使用<<       2.000000   0.580000   2.580000 (  2.635540)
————————————— total: 7.630000sec

                   user     system      total        real
加號連接   1.810000   0.600000   2.410000 (  2.476613)
放進引號   2.050000   0.600000   2.650000 (  2.656080)
使用<<       1.960000   0.600000   2.560000 (  2.567434)

因為使用了bmbm方式, 所以會有兩個結果, 第一個是演習結果, 第二個是真實結果.  如果使用bm方法, 將只會有一組結果.
結果有user時間, 系統時間, 總時間和實際花費的時間. 單位為秒.

從結果可以看出, 使用+連接兩個字串時速度最快, 而放進引號的方法最慢. 不過從結果也可以看出即使進行500000執行的結果也相差在0.3秒之內, 平時換用問題不大.

看來不是這一次, 希望下次你在自己的Benchmark試驗中, 會發現給你的程序帶來巨大速度提供的代碼.

發表在 Ruby on Rails | 留下評論

用ruby語言以句子為單位拆分一個字串

目標, 用ruby語言以句子為單位拆分一個字串. 如:
給出字串:
s="這是一個句子,另一個句子.一個新句子!難道這不是另一個句子嗎?"
將它分拆為:
 ["這是一個句子,"], ["另一個句子."], ["一個新句子!"], ["難道這不是另一個句子嗎?"]
樣式.
測試前將ruby的$KCODE環境變量設置為’u', 啟動UTF8編碼支持中文.
$KCODE=’u’
嘗試1:
>> s.split(/\.|,|\?|\!/)
=> ["這是一個句子", "另一個句子", "一個新句子", "難道這不是另一個句子嗎"]
等同於:
>> s.split(/[.,!?]/)
=> ["這是一個句子", "另一個句子", "一個新句子", "難道這不是另一個句子嗎"]
雖然分開了句子, 但失去了標點.

>> s.split(/([.,!?])/)
=> ["這是一個句子", ",", "另一個句子", ".", "一個新句子", "!", "難道這不是另一個句子嗎", "?"]
用括號將正則組成一組, 標點出來了, 但和句子是分開的.

改用scan
>> s.scan /.+?[.,?!]/
=> ["這是一個句子,"], ["另一個句子."], ["一個新句子!"], ["難道這不是另一個句子嗎?"]
成功了!!

如果一定要這樣:
>> s.scan(/(.+?(\.|\?|\!))/).collect{|p|p[0]}
=> ["這是一個句子,另一個句子.", "一個新句子!", "難道這不是另一個句子嗎?"]
也是可行的.

發表在 Ruby on Rails | 留下評論

svnX出錯的解決辦法

svnX是蘋果上的svn圖形管理軟件, 下面是我總結的常見錯誤解決辦法.
1.導入一個已經被SVN管理過的文件夾, 這時要先刪除原有的svn記錄:
到新移入目錄的根目前執行:
find ./ -name ".svn" | xargs rm -Rf
2.用svnx刪除一個文件夾出現 has no URL 錯誤.
手動用命令刪除:
svn delete app/folder
svn commit -m ‘mission impossible’
3.覆蓋文件後出現commit錯誤
先拿開那個文件或文件夾, 執行delete文件/文件夾操作, 然後放入新文件/文件夾, 執行add操作
4.ignore已經被收錄的文件/文件夾
方法同上, 先移開這些文件/文件夾, 執行delete操作, 然後
svn propset svn:ignore "*" app/folder
svn commit -m ‘ignore!!!’
然後再移回舊文件.
另: 今天剛下載了蘋果上的另一個svn管理工具Versions beta, 還沒詳細試用, 不清楚效果.

發表在 信息處理 | 一條評論

GPS

就在超市口的一個拐角, 他靠着綠化欄半躺在地上. 破破爛爛的衣服一塊灰一塊黑. 領域內擺着一個變形了的搪瓷碗. 碗里零星地散着幾個硬幣.
剛吃完午飯的他一邊有節奏地上下晃着斜歪着的頭, 一邊哼着什麼. 顯然是那種很適合看女人大腿時哼着的東西.
蒼蠅不時落在他的腳上. 他已經不對蒼蠅動手了. 開始是討厭, 然後他慢慢同情起這些飛蟲起來, 認為這些蟲子大概也樣是無家可歸的. 但, 現在這種同情也慢慢地淡漠了. 生活就是殘酷的 — 也許這就是三天後他認為更成熟的想法…
三天了! 終於三天了… 他一邊感覺到一種解脫, 同時竟也感覺到一種懷念…
就在這時, 突然傳來一首"月亮之上". 是一條短信: "北, 200米, 光頭".
他立馬起身, 從身後掏出一手槍.
"他媽的北在哪裡???"他愣了2秒, 但隨即掏出一手機大小的設備, 中間是一個血紅的大箭頭, 箭頭上方是四個斗大的漢字– "他媽的北"!

發表在 某時雨集 | 留下評論

感古都許昌

悠悠今日水
依依古灞陵
梟雄揮劍去
閑雲卻長停

發表在 某時雨集 | 留下評論