發表文章

目前顯示的是 十二月, 2013的文章

在 Ubuntu 下用 gdb debug CPython

用法和其它 library 稍微不同, 安裝 python-dbg 後, 是提供另一個含有 debug symbol 的 python 執行檔 python2.7-dbg, 而不是 gdb 自己另外載入 python 的 debug symbol。 可從 dpkg -L python-dbg 的結果得知這事:$ dpkg -L python2.7-dbg | grep bin/python /usr/lib/debug/usr/bin/python2.7-gdb.py /usr/lib/debug/usr/bin/python2.7 /usr/bin/python2.7-dbg /usr/bin/python2.7-dbg-config /usr/lib/debug/usr/bin/python2.7-dbg-gdb.py $ nm /usr/bin/python2.7 nm: /usr/bin/python2.7: no symbols $ nm /usr/bin/python2.7-dbg | head U ASN1_INTEGER_get@@OPENSSL_1.0.0 U ASN1_STRING_data@@OPENSSL_1.0.0 U ASN1_STRING_length@@OPENSSL_1.0.0 U ASN1_STRING_to_UTF8@@OPENSSL_1.0.0 U ASN1_TIME_print@@OPENSSL_1.0.0 U ASN1_item_d2i@@OPENSSL_1.0.0 00000000008857e0 d AST_type 0000000000967588 b Add_singleton 00000000009675e8 b Add_type 0000000000967560 b And_singleton 實際執行的結果:$ gdb --args python2.7-dbg -c 'import time; time.sleep(10)' GNU gdb (Ubuntu/Linaro 7.4-2012…

了解 2D Graphics Library 的基本知識

有很多套不同的 2D Graphics Library, 像是 Linux 下的 Cairo, OS X 和 iOS 下的 Quartz 2D 還有跨平台的 Skia, 但它們的概念應該差不多, 若看不懂其中一套, 可以參考別套的文件再回頭理解 (特別是 iOS 的文件最齊)。這篇記錄看了那些文件協助我了解 2D Graphics Library 的基本知識。 Cairo TutorialCairo Tutorial 說明 Cairo 的架構, 配合圖示和簡短的範例程式, 相當實用。 Cairo 的架構分成: source, mask, destination, context。可以想像 destination 是一塊畫布 (pixel buffer), 可能對應到 bitmap、螢幕、PDF 或印表機。使用 Cairo API 設定好 source (如顏色、漸層模式 (gradien) 或另一個畫布) 和 mask, 再決定繪圖的動作, 就會將 source 經過 mask 的結果複製到 destination。 context 管理目前設定的各種屬性, 若有用過 OpenGL 或其它繪圖函式庫, 應該不會對 context 的概念感到陌生。繪製的動作會參考 context 內設定的屬性。 整體來說, 使用 2D Graphics Library 就是先產生一個 pixel buffer (Cairo 稱為 cairo_surface_t), 然後產生一個包含 pixel buffer 的 context (Cairo 稱為 cairo_t)。接著設定 context 屬性、source、mask, 然後決定繪圖動作 (如 fill、stroke)。 PathCairo Tutorial 有介紹 path 是什麼。Cocoa with Love: 5 ways to draw a 2D shape with a hole in CoreGraphics 提到如何用 path 畫出不同的填色效果。用同一個例子的不同作法說明為何需要 non-zero winding ruleeven-odd rule。 Blending參考 Porter/Duff Compositing and Blend Modes 了解各種 blend mode 的計算方式和圖例…

在 Chrome DevTools 修改 CSS 並同步回檔案裡

Chrome DevTools 最近的新功能, 參考 Chrome DevTools Revolutions 2013 - HTML5 Rocks, 作法如下: DevTools: settings -> workspace, 點選 add folder 加入開發用的目錄。允許 Chrome 讀寫該目錄下的檔案。 開啟網址 (本機或網路上的), 在 DevTools 的 source panel 找到要同步存檔的檔案, 按右鍵選 Map to Network Resource。 重新載入該頁。 注意: 即使直接開啟 workspace 目錄內的檔案, 仍需要執行 "Map to Network Resource" 該步, 沒作這步讓我卡了一陣子 ...。 只能同步存外部 CSS 檔, html 本體無法同步存檔, 仍得自己按 Ctrl+S。 成功後改網頁就快多啦, 在 html 內寫好骨架, 幫主要元件加上 class, 之後就在 DevTools 內選 tag, 直接在 class 內加 CSS rules, 調整參數。調整的當下就會存回檔案了, 真是超爽的啦。 備註: 依官方的說明, 也可以同步 Sass。

Mobile Safari 和 Chrome on Android 上的 1 pixel 間距

參考 CSS Tip: How to Prevent Div Seam Lines from Appearing in Apple's Mobile Safari | Oddo Design, 解法很簡單: position: relative; top: 1px; 似乎是 webkit 的 bug, 搜 "mobile safari 1 pixel gap" 可看到很多討論。 position: relative 真好用, 不只可以用來疊底, 加裝飾, 也可以 workaround 瀏覽器的 bug。

網頁顯示順序的規則: stacking context

瀏覽器在繪出網頁內容時, 並不是單純在 CSS 的 z-index 排序。而是依 stacking context。 有兩篇很棒的說明文章:The stacking context - Web developer guide | MDN: 一圖勝千文, 說明什麼是 stacking context。What You May Not Know About the Z-Index Property – Tuts+ Tutorials: 進一步說明 stacking order。由此得知為何文字 (嵌在 inline box 裡) 一定顯示在 div (block level box) 之上。這篇似乎不是用標準定義的詞彙, 不過比較容易理解。

g++ 最佳化 switch-case 的一個小例子

最近看到一段程式如下: bool isOkay(Type type) { switch (type) { case A: case C: case D: case E: case G: case I: case K: case L: case Y: return false; default: ; } return true; } 原本想說 switch-case 和一串 if 沒差太多, 這樣寫應該比 set 慢。畢竟從演算法的角度來看, 前者是線式比對, 複雜度和 type 特例的數量成正比, 而 set 保證是 O(1)。 後來經 command 提醒, 想說搞不好 compiler 有做最佳化, 還是來看產生的組語好了。結果 compiler 真的有做最佳化, 從組語來看, switch 不見得會比較慢。觀察用的程式見這裡, 用 g++ -O2 產生的組語見這裡。 結論是: 寫成「一串 if」, 結果的確是一串 cmp 和 je, 複雜度如原本預期。 但是 switch 讓 compiler 知道比較同一個變數, compiler 有機會做最佳化, 變成少數幾個計算和比較。 使用 set 有額外呼叫函式的成本, 對於簡單計算的例子, 是不可忽略的額外成本。 使用 -O2 後, set 的版本有些複雜, 沒辦法藉由「大概看看+腦補推測」搞懂。實測的結果如下:$ g++ -O2 benchmark_switch_cases_check.cpp -DSWITCH; time ./a.out; 1700000000 real 0m6.398s user 0m6.396s sys 0m0.000s $ g++ -O2 benchmark_switch_cases_check.cpp -DALOTIF; time ./a.out 1700000000 real 0m8.392s user 0m8.389s sys 0m0.000s $ g++ -O2 benchmark_switch_cases_check.cpp -DIF; time ./a.out 1700000000 real 0m8.4…