Safari的Web Worker速度非常搶眼

 Wed, 07 Oct 2009 10:43:37 +0800

為了測試自己寫的PHP Tokyo Cabinet Extension是否在多人運作下不會有問題,興起了利用Web Worker來做測試的念頭。

(按:我自己寫的extension只是包裝他的tcadb函式庫,這樣就可以做local access他的資料庫檔案或是記憶體資料庫。其實透過Tokyo Tyrant才是最好方法,Plurk的LightCloud也是基於Tokyo Tyrant的。Tokyo Tyrant已經有初期的PECL Connector可以支援,同時也有純PHP實現的Connector。)

簡單的測試程式如下:

<?php
header("Pragma: no-cache");
/*$tt = new TokyoTyrant();
$tt->connect( 'localhost', 1978 );
$c=$tt->add('count525',0);
$c1 = $tt->add('count525', 1);
echo '{result: "'.$c1.':'.($c1-$c).'"}';*/
$tcadb = tcadbnew();
tcadbopen($tcadb, 'test.tch');
$c = tcadbaddint($tcadb, 'count525', 0);
$c1 = tcadbaddint($tcadb, 'count525', 1);
tcadbclose($tcadb);
echo '{result: "'.$c1.':'.($c1-$c).'"}';
(註解掉的部份是用PECL的Tokyo Tyrant Connector做的程式)

簡單地說,就是counter啦...每次access會加1,同時檢查在加1之前之後的數字是否只增加1,看看會不會有操作問題。 接下來是Web Workder,首先是html與內嵌的Javascript:

<html>
<body>
<div id="panel"></div>
</body>
</html>
<script>
    var w = [];
    var i = 0;
    var limit = 975;
    var count = 0;
    var start = new Date().getTime();
    for (;i<25;i++) {
        w[i] = new Worker('test525.js');
        w[i].onmessage = function(e) {
            document.getElementById('panel').innerHTML += e.data + '<br>';
            if (count<limit) {
                this.postMessage(10);
                count++;
            } else {
                var duration = new Date().getTime() - start;
                document.getElementById('panel').innerHTML += "duration: "+duration+"<br>";
            }
        }
        w[i].onerror = function(e) {
            throw(e.data);
        }
        w[i].postMessage(10);
    }
</script>

接下來是worker的程式:

onmessage = function(e) {
    var w = new XMLHttpRequest();
    w.onreadystatechange = function() {
        if (w.readyState==4) {
            clearTimeout(tid);
            if (w.status == 200) {
                postMessage(w.responseText);
            } else {
                postMessage('{result: \'error: '+w.status+'\'}');
            }
        }
    }
    w.onerror
    w.open("GET", "test525.php", true);
    w.send(null);
    var tid = setTimeout(function() {
        postMessage("{result: -1000}");
    }, 1000*30);
}

這樣就可以讓25個worker做大約1000次access。如果網路環境單純,counter的增長看起來幾乎是依照順序的,偶而有例外,如果開不同的瀏覽器,可以看到counter的數字會變得不連續,但是基本上counter累加的計算沒有被干擾,不過我想恐怕需要做更複雜一點的測試才能知道這樣是否不會有race的問題(就是php extension的部份),不過tokyo cabinet有支援transaction操作,也許要一併測試......

Firefox3.5、Chrome3與Safari4都已經支援worker,Opera10似乎還不支援。速度上,則是Safari4 > Chrome3 > Firefox3.5,而且Safari4跑web worker真的很快,我想Safari團隊在這一部份恐怕有特別下功夫,其他瀏覽器要加油了。


2009-10-7 13:55 補充:

在公司測試,很訝異地發現,Safari4的速度飛快,Chrome3牛步化,跟Firefox的差距不大...我猜恐怕Chrome3在net access上有一些效能瓶頸。(差距很明顯,同樣的測試,Safari4只花34秒,Chrome3花了215秒,Firefox3.5花了222秒。測試方式一樣是用25個worker跑大約一千次access。)


2009-10-7 21:09:09

另一個有趣的現象,在家裏用區網連伺服器,Chrome3用了13秒,Safari4用了17秒。換到用外網連到伺服器,Chrome3變成18秒,Safari4還是17秒。Safari4用了怎樣的技術嗎?真是有趣。