bonobo-js icon indicating copy to clipboard operation
bonobo-js copied to clipboard

How to use transferable objects efficiently?

Open mhelvens opened this issue 11 years ago • 5 comments

I've tried to send JSON-like objects from a worker thread to the main thread using Bonobo. This still seems to take up to 10 seconds for large arrays. I profiled my app, and nearly all of this time is used by Bonobo function _self.messageHandler.

Question 1: The Bonobo docs claim that Bonobo intelligently uses transferable objects to make the transfer more efficient. From what I've been able to figure out, however, objects are translated to ArrayBuffers, which are then transferred, when are then translated back to their original form. Is that correct?

Question 2: From what I understand of web-workers, there is native support for copying JSON objects from thread to thread, using structured clone. Is this 'transferable-object-inbetween' approach really more efficient, given that it requires two translations, one of them in the main thread?

Question 3: What sort of data does Bonobo accept to actually get the (near) zero transfer time promised by transferable objects? If I send a raw ArrayBuffer, will it send it directly, or still try to copy? What about an object that contains raw ArrayBuffers?

mhelvens avatar Mar 02 '15 15:03 mhelvens

Hi Michiel,

  1. This is correct, Bonobo will parse an object or array into a string which is then converted into an ArrayBuffer. ArrayBuffers are transferrable and therefore there is no overhead passing between threads. Unfortunately, this transformation into a transferrable object and back again still takes some time.
  2. Unfortunately, passing a JSON object from thread to thread natively is as simple as the browser stringifying the object and passing the string between threads, then parsing it on the other end. Unfortunately those strings are no transferrable objects and therefore these can take some time to transfer, as well as the JSON operations.
  3. I would definitely suggest using TypedArrays where possible. In the previous issue you were transferring a large plain array of floats. I would suggest using a Float32Array, this requires no transformation before transfer, so you should see a noticeable decrease in time.

In any case, I would suggest minimising the amount of large transfers between threads by perhaps chunking larger objects into parts and transferring these, effectively splitting the workload.

Let me know if this helps. I am happy to look at your codebase as well ;)

f5io avatar Mar 02 '15 17:03 f5io

Unfortunately, passing a JSON object from thread to thread natively is as simple as the browser stringifying the object and passing the string between threads, then parsing it on the other end.

Not according to the HTML5 standard. Apparently JSON-like data is copied using the structured cloning algorithm. It can also handle things that are not JSON, like objects with cyclic references. I'm pretty sure Bonobo misses out on those.

Even leaving that aside, I wonder how Bonobo's approach could possibly be faster:

postMessage: (1) → [structured cloning] → (2) Bonobo.emit: (1) → [JSON.stringify] → [convert] → [transfer] → [convert] → [JSON.parse] → (2)

Yes, Bonobo has a zero-time transfer in the middle. On the other hand, it needs all those other operations. Have you actually run benchmarks? Because I'm willing to bet that the Bonobo approach only makes the overall transfer slower. And if that's the case, then what's the point? You could greatly simplify your code if you relied on structured cloning instead. Am I misunderstanding the Bonobo approach?

mhelvens avatar Mar 04 '15 19:03 mhelvens

Yeah, I've had a quick look at this and I was wrong. ;)

I'll be having a look into this over the next couple of days. Should be reasonably easy to implement.

f5io avatar Mar 04 '15 20:03 f5io

Whatever happened to this issue? Has it been resolved to where objects are now fully transferable in Bonobo?

markeberhart avatar Mar 20 '17 02:03 markeberhart