2014年6月26日 星期四

我為何仍繼續使用 Macports 而不用 Homebrew

很多人因為 Macports 在裝一些套件時,無法避免的另外編譯另外一套 Perl 裝至系統而跳槽使用 Homebrew。但身為一個前 Perl Developer,直接使用 System Perl as a dependency 其實並不太安全。

其一:  Mac OS 本身在升級時,會自動將 Perl 版本升級,如果你 link 至舊版的 Perl,升級之後你的 Homebrew 套件所有相依 System Perl 幾乎都要重新編譯才行。

但用 Macports 裝,則是將套件完全獨立一個空間出來,把套件跟 System library 的接觸面減到最小,就算是升級 Mac OS ,只要不是 32 位元轉 64 位元,原本編譯的套件幾乎都可以繼續使用。

其二:  Macports 現在提供 pre-built 好的套件安裝檔,安裝 package 幾乎不再需要重新編譯,Installer 自動下載解開就裝完了,完全不浪費 CPU。但目前 Homebrew 裝套件應該都是要重新編譯的。

其三:  安裝或升級套件,Macports 會自動幫你掃描是不是有 Broken library,若有問題也會自動重裝 library。(目前看起來 Homebrew 沒這個功能 ?)

其四: Homebrew 雖然 Formula 眾多,但安裝非官方的 Formula 有時容易引起套件衝突,舉例來說 PHP 編譯有各種 configure options,各家使用的 default configure options 又不一樣,安裝 extension 的時候還會彼此影響到... 有些 Formula 還必須先查看是否有 enable 某功能,不然裝了也是白裝。

其五: Homebrew 編譯套件不像 Macports 提供客製化 variants,你用某個 Formula 裝就是固定只能裝他預先指定好的 features,要客製化只能自己複製出來改,自己複製出來改就累了,你還得自己 maintain forumla 才行。 (更新: 據說 Homebrew 後來也支援了 option,不過升級套件要自己記住當初裝的 option 才行)


2014年6月14日 星期六

一些關於 API 設計的碎碎念

平常可能寫 API 寫久了沒什麼感覺,但最近對於 API 設計感想特別多...碎碎念罷了。

1. 各種參數的 naming 如果沒有 consistent,在不同的 context 下會很容易造成混淆,譬如說同一個參數名稱在 A context 是某種 Type,B context 卻是另外一種 Type。

這樣的命名混淆,在一整個 process flow 裡面,一旦遇到不同的呼叫使用相同名稱卻在不同 context 有不同意義的參數,就會成為杯具。

再怎麼樣想不到適合的名字也不該用混淆的名字

2. 命名歸類的一致性: 譬如說某某 method 是 A 相關,可以 A 作為 prefix,那就不要突然 A 突然 B 突然又 C,否則誰知道是在幹嘛(丟鍵盤)

3. 函式命名沒有這麼難,就算不知道怎麼命名也至少用動詞加受詞 (V+OBJ) 吧,然後 OBJ 的名稱一定要一致,不要一下 memberInfo 一下 memberData 的。

4. 此外 method name 本身的命名應該要讓人能讀出 read-only / write 等資訊,而不是一個看起來明明是 read-only 的 API 本身卻包含了 write 的行為。

5. 參數類型、可選不可選、臨界值、長度、不同值所代表的隱含行為在文件上寫清楚也是相當重要的,否則呼叫方若誤解了參數所帶來的隱含操作,則會造成系統不穩定。

6. 另外參數名稱也請不要用 1234567 當 suffix 呀,若是為了安全性,你好歹也用英文縮寫。

7. 最後,至少寫個 persistent layer 的 test 吧,curl 腳本也行,不要一下噴 HTML 一下 XML 的,明明都送 Accept: text/xml 啦!

2014年6月11日 星期三

Perl URL Router Benchmarks

To improve the overhead of URL routing, I developed a tiny URL routing library in C - R3, which is designed for high performance and low memory usage.

The implementation uses the trie data structure. Trie is an efficient information retrieval data structure, which uses a prefix tree to search inserted strings by their common prefix, thus it's pretty fast for matching routes.

The tricky part of R3 is that we need to support regular expression patterns in our routing definition to dispatch path dynamically, thus R3 implemented a variant of Trie by mixing some concepts of DFA, not just simply inserting plain string paths into the prefix tree.

There are several comparison types in R3: plain string, opcode or regular expression pattern. Each node have its own comparison type to dispatch the path to their own children.

For those simple regular expression patterns, R3 compiles the regular expressions into opcodes to enhance the comparison speed and it's twice faster than using PCRE library to match the path with the patterns.

And since there are a lot of things to do before the matching operation, the whole tree structure needs to be compiled before dispatching paths.

Here is the continuous benchmark result of R3 itself, The C version R3 can dispatch over 11 million plain string paths per second.

A talented Perl hacker - Cindy Wang developed a CPAN module based on R3 library - Router::R3, which has become the fastest routing module on CPAN. It's so fast that you just can't deny.

The Perl version R3 (Router::R3) can dispatch nearly 1 million paths per second while Journey (The Rails router) dispatches 9.9 thousand plain string paths per second.

We also used the routing path generator from the rails' pull request stevegraham/rails/pull/1 to benchmark the Perl URL routers on CPAN, including HTTP::Router, Router::Simple, Router::Boom and Router::R3

There are over 3 hundred generated routing paths in the benchmark script. we tested the "plain string matching" with the route in the middle of the list, and also the first route matching, regular expression matching.

Here comes the dispatching speed result:

Benchmarking 'plain string matching' by path '/corge/quux/bar'
===============================================================
                Rate  HTTP::Router Router::Simple  Router::Boom    Router::R3
HTTP::Router      203/s            --           -89%         -100%         -100%
Router::Simple   1782/s          779%             --          -99%         -100%
Router::Boom   168658/s        83094%          9365%            --          -82%
Router::R3     954407/s       470684%         53461%          466%            --
Benchmarking 'regexp string matching' by path '/post/2012/03'
===============================================================
                Rate  HTTP::Router Router::Simple  Router::Boom    Router::R3
HTTP::Router     1076/s            --           -88%          -99%         -100%
Router::Simple   9309/s          765%             --          -91%          -97%
Router::Boom   104387/s         9602%          1021%            --          -66%
Router::R3     306925/s        28426%          3197%          194%            --
Benchmarking 'first charactar matching' by path '/'
===============================================================
                    Rate  HTTP::Router Router::Simple Router::Boom    Router::R3
HTTP::Router      3839/s            --           -87%         -98%         -100%
Router::Simple   30545/s          696%             --         -83%          -98%
Router::Boom    180555/s         4603%           491%           --          -88%
Router::R3     1535999/s        39910%          4929%         751%            --

2014年6月10日 星期二

評 Microsoft Sculpt 人體工學鍵盤 (Microsoft Sculpt Ergonomic Keyboard)

Microsoft Sculpt Keyboard 在造型上及人體工學上的設計實在無懈可擊。 但有幾個缺點造成相當多的不便:

1. Dongle 只能貼在滑鼠上,所以如果要帶鍵盤外出,就得連滑鼠一起帶。不然就是得把 Dongle 放口袋或其他地方,加上 Dongle 太小了... 非常容易弄不見。

根據 HLB 的敘述,Dongle 弄不見之後竟然沒有辦法維修或另外購買!!! 就算你願意花錢買 Dongle 也不行!

2. 鍵盤帶著外出,由於完全沒有電源開關,所以只要壓到鍵盤,就會造成電量損失,放上一整天隔天就會沒電! 所以帶著外出時,還要先把電池全部卸下........