大貓共和國

Meow

Blogtrans已知問題

似乎因為無名又做了微妙的決定,最近想要搬Blog的人又變多了,我收到不少Blogtrans有關的Bug。

Blogtrans現在有一些已知的問題:

  • 匯入無名備份檔時可能會卡住 (應該是無名匯出格式不知道偷偷做了什麼變動)
  • 匯出至Blogger時留言會不見 (這個以前可以的,應該是Blogger改了讀備份檔的機制)
  • 無法正常處理簡體中文
因為在下最近很忙(背景音樂:不用麻煩了,不用麻煩了,阿宅很忙的),應該會趁這周末的時間(5/1~5/3)修正這些問題。如果E-mail給我沒有回音,可以下周一後再過來看看有沒有更新

Ruby v.s. Python: Operator +=

剛剛在Godfat的Blog看到這篇文章,比較了Ruby和Python在對於list進行+=運算子操作的差異:

[~/test]# irb
irb(main):001:0> a = b = []
=> []
irb(main):002:0> a += [1]
=> [1]
irb(main):003:0> a
=> [1]
irb(main):004:0> b
=> []
irb(main):005:0>
Python 2.5.1
>>> a = b = []
>>> a += [1]
>>> a
[1]
>>> b
[1]

這個結果同樣的出乎我的意料之外,所以花了些時間研究一下。以下分別討論a=b=[]; a+=[1]在Ruby和Python的運作狀況。

先看看a=b=[]。毫無疑問,不管在Ruby或Python,這個敘述都是「造一個空list,並讓a和b指向同一個list」。如果你被上面的例子迷惑了,試試:

irb(main):001:0> a = b = []
=> []
irb(main):002:0> a << 1
==> [1]
irb(main):003:0> a
=> [1]
irb(main):004:0> b
=> [1]
irb(main):005:0>

再來,先討論Python
Python的a+=[1]等價於a.iadd([1])
對呼叫a+=[1]的block,變數a所綁定的物件不會改變
既然a和b所綁定的物件相同,那a和b的內容理所當然也會一樣

再來看看Ruby的a+=[1]
雖然Ruby可以覆載運算子,但+=運算子是不能被覆載的
簡單的試試

Ruby的method可以名為+,可以以=結尾,就是不能名為+=。同理,-=, *=, /=, &&=, ||=之類的也不行。參考Programming Ruby

In common with many other languages, Ruby has a syntactic shortcut: a=a+2 may be written as a+=2.
可以得到結論:a+=[1]只是一個Syntax sugar,可以想像他parse時就變成了a=a+[1],而不是由a去invoke一個名為+=的member function。

差異就在這邊,對呼叫a+=[1]的block來說,a+[1]造出了一個新物件,再綁定到變數a上,所以a和b指向不一樣的東西

這裡或許值得注意的是,要是Ruby中+=是一個member method,那a+=[1]就很難不影響到b。因為對呼叫a+=[1]的block來說,他只是去呼叫a的一個member method。完成之後a與b還是指向同一個object。像a<<b就是這樣的例子。

另外,這些敘述應該是等價的:
  • Python的a+=[b]
  • Python的a.append(b)
  • Ruby的a<<b
  • Ruby的a.push b
這也造就了Ruby和Python對於a+=b語意本質上的不同。

我個人是Python和Ruby都有在用,在這個小地方上我比較喜歡Python的作法:將+=視為member function,operator的left operand所綁定的目標不會改變。知道這點的話,Python應該是易了解又有一致性。

JustFuck, a X86 Just-In-Time Compiler for Brainfuck

前陣子看到Jserv介紹asmjit的文章,一直想找機會試試看。另外,最近ptt的programming版上的一個thread出現了很多esoteric programming language,讓我想到可以試試寫個Brainfuck JIT Compiler。於是,這個專案就誕生了?

JustFuck, A x86 Just-In-Time Compiler for Brainfuck

我不是故意罵髒話的啊….他的縮寫很自然就這樣啊….(大誤)

一位不知名的鳥類程式設計師評論道:「真是太神奇了,我從未見過腦幹語言運行的如此飛快,嘎嘎。」

因為最近開始學git,所以放github上:Project page

Source code只有一個檔案,三百行。學習Brainfuck, asmjit, git的實驗品,大概懶得再重構更新了。

Google Chrome在EeePC上的效能調校 (適用於其他SSD硬碟的電腦)

前幾天我寫了一篇Google Chrome瘋狂讀寫硬碟的問題,說明了Google Chrome在EeePC等使用SSD硬碟的電腦上,可能會因為大量的硬碟存取,導致系統緩慢。然而,Google Chrome超快的JavaScript Engine對我來說仍是相當具有吸引力。因此,今天我想進一步探討Chrome在EeePC這種使用SSD硬碟的電腦上要如何調校。

觀察一下Google Chrome的使用者資料目錄,我們會發現有兩個東西占了大部份的空間:

  1. Safe Browsing這個檔案 (我的電腦中目前這個檔案的大小是50MB左右)
    Google Chrome的Safe Browsing功能,會自動從網路上下載惡意網站的黑名單。用Hex Editor打開看看,原來他是SQLite3的格式,使用SQLite3的瀏覽程式就可打開觀查,裡面存放了黑名單的IP資料。或許這就是硬碟瘋狂存取的元兇之一。
  2. Default\Cache資料夾中的檔案
    這個資料夾中則是格式不明的檔案,應該是網頁內容的快取檔案。另外,Google Chrome也對快取的頁面提供了非常迅速的全文檢索功能。因此,我推測這個資料夾中,應該也包函了全文檢索所需要的索引資料。
在上一篇文章中,我已經提到過使用RamDisk加速Google Chrome的方式。然而使用RamDisk時如果要使用Safe Browsing功能,則你有兩個選擇:
  1. 在開/關機時備份Safe Browsing資料,不過這樣必需在開關機時多複製50MB的資料,大幅降低EeePC開關機迅速的優勢。
  2. 在開/關機時不備份Safe Browsing資料,但這樣會造成每次重開Google Chrome時,都需要重新下載Safe Browsing資料,而造成頻寬的浪費
於是,我選擇停用Safe Browsing功能。只要使用網路夠小心,具有相當的網路安全知識,我相信這個功能是沒有那麼必要的。

重新整理一下我的EeePC效能調校步驟:
  1. 安裝RamDisk,假設將RamDisk安裝到磁碟機代號R
  2. 將Chrome的使用者資料路徑移到RamDisk上。
    在Google Chrome的執行捷徑上加上參數:
    –User-data-dir=R:\ChromeUserData
  3. 進到Google Chrome,至選項=>進階選項=>安全性
    取消「啟用釣魚網站及惡意程式防護」
  4. 關閉Google Chrome,至R:\ChromeUserData
    如果已存在名為Safe Browsing開頭的檔案,將其刪除
  5. 在你的硬碟建立一個資料夾,做完RamDisk的資料備份用
    我建立在C:\RamDiskImg (以下都以此資料夾為例)
  6. 建立兩個批次檔,分別在開機及關機時自動執行
    開機批次檔:
    xcopy /s /y /k C:\RamDiskImg*. R:<br />關機批次檔:
    set ramDiskImgDir=C:\RamDiskImg
    md %ramDiskImgDir%\ChromeUserData
    xcopy /s /y /k "R:\ChromeUserData\Local State" %ramDiskImgDir%\ChromeUserData<br />xcopy /y /k R:\ChromeUserData\Default*.
    %ramDiskImgDir%\ChromeUserData\Default<br />xcopy /s /y /k "R:\ChromeUserData\Default\Plugin Data*.*" "%ramDiskImgDir%\ChromeUserData\Default\Plugin Data\"
    (第一行可以代換成你的RamDisk備份目錄)
  7. 接下來設定開關機時自動執行這些批次檔:
    開始=>執行=>鍵入gpedit.msg
    點選電腦設定=>Windows設定=>指令碼 - (啟動/關機)
    分別將開機批次檔、關機批次檔加到啟動/關機的指令碼中
目前我這樣調整,覺得已經相當OK了。執行速度快,開關機時需要製少量資料,可以保留個人設定及Cookie (注意,網頁快取在關機後將不會被保留下來) 。

參考資料:


Update:
現在我在PC上跑Chrome,也會有因為硬碟瘋狂讀寫的現象了,2G Ram+E8400 CPU都慢到不像話。把Safe Browsing關了就一切正常,Google Chrome Help上的Thread也有提到這個問題。我猜測Chrome在Safe Browsing上不知道做了什麼鳥事?每下載一筆IP記錄就用一個Transaction去更新sqlite資料庫嗎?反正先停用Safe Browsing,等待Google修正這個問題吧….

Google Chrome瘋狂讀寫硬碟的問題

在EeePC上面使用了幾天的Google Chrome,我發現一個問題:Chrome程式執行一段時間後,就會開始瘋狂的讀寫硬碟,但CPU使用率仍是0%左右,使系統的整體速度變慢許多 (很明顯是I/O Bound) 。尤其對於EeePC這樣使用固態硬碟的筆電來說,一直讀寫硬碟須要比一般硬碟更多的時間,更會大量減低硬碟的壽命。對於使用一般HDD硬碟的電腦來說,似乎感受不太到這個問題。

在網路上找到這個解決方法:用Ramdisk彻底解决Chrome对硬盘疯狂折磨

簡單摘要一下:

  1. 安裝RamDisk
  2. 將Chrome的使用者資料路徑移到RamDisk上。
    在Google Chrome的執行捷徑上加上參數:
    –User-data-dir=R:\UserData
  3. 如果希望關機要保留使用者資料,就使用一些批次檔在關機/開機時執行備份/回復的動作
至於為什麼Chrome會這樣大量讀寫硬碟,上面的文章倒是沒提到。但我個人猜測:Chrome提供了對頁面快取進行全文檢索的功能,大量的讀寫硬碟應該是在建立全文檢索的索引吧。