ActionScript Worker Message Passing is Slow(ActionScript 线
Originaly From: http://jacksondunstan.com/articles/2390 Since Flash Player 11.4 was released we have finally been given the ability to run multiple threads of AS3 code to take advantage of modern multi-core CPUs. However,when we start writing this multi-threaded code we immediately run into the requirement to coordinate the threads by passing messages between them. As it turns out,this is quite slow in AS3. Read on for the performance analysis.
The following test app performs a very simple task in two ways. The main thread passes a series of integers to a worker thread and the worker thread adds those integers together to compute their sum. Two ways of accomplishing this task are used. The first way passes 1000 individual messages to the worker thread,each with an integer to add. A final message is passed to tell the worker to pass the sum back to the main thread and clear for the next test. The second way of computing the sum creates a These two ways have been designed such that one passes a lot of messages and the other only passes one. Check out the source code for details. ? package { import flash.display.Sprite; import flash.events.Event; import flash.utils.getTimer; import flash.utils.ByteArray; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.system.Worker; import flash.system.WorkerDomain; import flash.system.WorkerState; import flash.system.MessageChannel; public class MessageChannelTest extends Sprite { private var logger:TextField = new TextField(); private function row(...cols): void { logger.appendText(cols.join(",")+"n"); } private var mainToWorker:MessageChannel; private var mainToWorkerBytes:MessageChannel; private var mainToWorkerClear:MessageChannel; private var workerToMain:MessageChannel; private var worker:Worker; private var REPS:int = 100000; private var beforeTime:int; private var sum:int; private var correctSum:int; public function MessageChannelTest() { logger.autoSize = TextFieldAutoSize.LEFT; addChild(logger); if (Worker.current.isPrimordial) { startMainThread(); } else { startWorkerThread(); } } private function startMainThread(): void { worker = WorkerDomain.current.createWorker(this.loaderInfo.bytes); mainToWorker = Worker.current.createMessageChannel(worker); worker.setSharedProperty("mainToWorker",mainToWorker); mainToWorkerBytes = Worker.current.createMessageChannel(worker); worker.setSharedProperty("mainToWorkerBytes",mainToWorkerBytes); mainToWorkerClear = Worker.current.createMessageChannel(worker); worker.setSharedProperty("mainToWorkerClear",mainToWorkerClear); workerToMain = worker.createMessageChannel(Worker.current); workerToMain.addEventListener(Event.CHANNEL_MESSAGE,onWorkerToMainDirect); worker.setSharedProperty("workerToMain",workerToMain); worker.start(); for (var i:int = 0; i < REPS; ++i) { correctSum += i; } row("Type","Time","Correct?"); sum = 0; beforeTime = getTimer(); for (i = 0; i < REPS; ++i) { mainToWorker.send(i); } mainToWorkerClear.send(true); } private function startWorkerThread(): void { mainToWorker = Worker.current.getSharedProperty("mainToWorker"); mainToWorkerBytes = Worker.current.getSharedProperty("mainToWorkerBytes"); mainToWorkerClear = Worker.current.getSharedProperty("mainToWorkerClear"); workerToMain = Worker.current.getSharedProperty("workerToMain"); mainToWorker.addEventListener(Event.CHANNEL_MESSAGE,onMainToWorker); mainToWorkerBytes.addEventListener(Event.CHANNEL_MESSAGE,onMainToWorkerBytes); mainToWorkerClear.addEventListener(Event.CHANNEL_MESSAGE,onMainToWorkerClear); } private function onMainToWorker(event:Event): void { sum += mainToWorker.receive(); } private function onMainToWorkerBytes(event:Event): void { var bytes:ByteArray = mainToWorkerBytes.receive(); bytes.position = 0; var numInts:int = bytes.length / 4; var sum:int; for (var i:int; i < numInts; ++i) { sum += bytes.readInt(); } workerToMain.send(sum); } private function onMainToWorkerClear(event:Event): void { workerToMain.send(sum); sum = 0; } private function onWorkerToMainDirect(event:Event): void { sum = workerToMain.receive(); var afterTime:int = getTimer(); row("Direct",(afterTime-beforeTime),(sum==correctSum)); workerToMain.removeEventListener(Event.CHANNEL_MESSAGE,onWorkerToMainDirect); workerToMain.addEventListener(Event.CHANNEL_MESSAGE,onWorkerToMainBytes); var bytes:ByteArray = new ByteArray(); bytes.shareable = true; bytes.length = REPS*4; bytes.position = 0; sum = 0; beforeTime = getTimer(); for (var i:int; i < REPS; ++i) { bytes.writeInt(i); } mainToWorkerBytes.send(bytes); } private function onWorkerToMainBytes(event:Event): void { sum = workerToMain.receive(); var afterTime:int = getTimer(); row("ByteArray",(sum==correctSum)); } } }
Run the test I ran this test in the following environment:
And here are the results I got: The (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |