ただしメインスレッド以外はHTMLエレメントにアクセス出来ないとかActiveXObjectは使えないとか色々制約があります。
制約があってできることが少ないというのは、逆に言えば「シンプルな状態」であり、もしかして、制約がある代わりに処理が高速だったりするのでは!?と思って先日比較テストしましたが、もう少し分かり易いデータが取得できました。
テスト用ソース
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<title>web worker</title> | |
</head> | |
<body></body> | |
<script type="text/jscript"> | |
resizeTo(400,100) | |
function getFunctionBody(fun){ | |
return fun.toString().trim().match(/^function[\s\w]*\([\w\s,]*\)\s*{([\w\W]*?)}$/)[1] | |
} | |
function fun2Worker(fun){ | |
var str=getFunctionBody(fun), blob=new Blob([str], {type:'text/javascript'}), url=URL.createObjectURL(blob), worker | |
try{worker = new Worker(url)} | |
catch(e){ | |
// Workerに渡すアドレスは同一生成元ポリシーを守らなければいけない。 | |
// 変数urlの中身は「brob:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX」のランダムな文字列 | |
// 呼び出し元ファイルのアドレスがローカルのものなら、ローカルPathしか渡せない。 | |
var fs=new ActiveXObject('Scripting.FileSystemObject'), path=fs.getSpecialFolder(2)+'/'+fs.getTempName()+'.js', ws=fs.CreateTextFile(path) | |
ws.Write(str) | |
ws.Close() | |
worker = new Worker(path) | |
} | |
return worker | |
} | |
worker = fun2Worker(function(){ | |
// ワーカー側スコープ | |
onmessage = function(e){ | |
共用 = e.data | |
for(name in 共用){eval(name + ' = ' + 共用[name])} | |
postMessage(試験()) | |
} | |
}) | |
worker.onmessage = function(e){ f1('work:'+e.data+'\n') } | |
共用={ | |
試験:function(){ | |
// 一定期間内により多くカウントできるスレッドが速い | |
var core=function(){ | |
var 開始=f0(), 期間=1000, カウント=0 | |
while((f0()-開始) < 期間){ カウント++ } | |
return カウント | |
} | |
for(var i=0,回数=5,arr=[],sum=0; i<回数 ;i++){ sum += arr[i] = core() } | |
return ['Max:'+Math.max.apply(null,arr), 'Min:'+Math.min.apply(null,arr), 'average:'+Math.round(sum/回数)] | |
}, | |
f0:function(){return (new Date()).getTime()} | |
} | |
f0 = 共用.f0 | |
// functionはpostできないので一旦文字列に置換する。 | |
obj={} | |
for(name in 共用){obj[name] = 共用[name].toString()} | |
worker.postMessage(obj) | |
文字列 = '' | |
f1=function(str){文字列 += str} | |
onload=function(){ | |
f1('main:'+共用.試験()+'\n') | |
setTimeout(function(){document.body.innerText = 文字列}, 10000) | |
} | |
</script> | |
</html> |
実行結果

Max、Min、Averageのすべてで、workよりもmainの方が37%程度高い数字になっています。
つまりWebWorkerで作成したスレッドは様々な制約がある上にちょっと遅いということです。。
まぁ、それでも無いよりはマシですが。。
ちなみに実行したPCのCPUはi5-4590です。
0 件のコメント:
コメントを投稿