ट्रांसफ़र किए जा सकने वाले ऑब्जेक्ट - बहुत तेज़ी से चार्ज होते हैं

Chrome 13 ने स्ट्रक्चर्ड क्लोनिंग नाम के एल्गोरिदम का इस्तेमाल करके, वेब वर्कर को/से ArrayBuffer को भेजने की सुविधा लॉन्च की है. इससे postMessage() एपीआई को ऐसे मैसेज स्वीकार करने की अनुमति मिली जो न सिर्फ़ स्ट्रिंग के थे, बल्कि File, Blob, ArrayBuffer, और JSON ऑब्जेक्ट जैसे जटिल टाइप थे. Firefox के नए वर्शन में भी स्ट्रक्चर्ड क्लोनिंग की सुविधा उपलब्ध है.

ज़्यादा तेज़ बेहतर है

स्ट्रक्चर्ड तरीके से क्लोनिंग की सुविधा बेहतरीन है, लेकिन फिर भी इसका इस्तेमाल कॉपी किया जा सकता है. किसी वर्कर को 32 एमबी ArrayBuffer पास करने का ओवरहेड सैकड़ों मिलीसेकंड में हो सकता है. ब्राउज़र के नए वर्शन में मैसेज पास करने की सुविधा के लिए, परफ़ॉर्मेंस में बड़ा सुधार किया गया है. इसे ट्रांसफ़र किए जा सकने वाले ऑब्जेक्ट कहते हैं.

ट्रांसफ़र किए जा सकने वाले ऑब्जेक्ट में, डेटा को एक कॉन्टेक्स्ट से दूसरे कॉन्टेक्स्ट में ट्रांसफ़र किया जाता है. यह ज़ीरो-कॉपी है. इससे किसी वर्कर को डेटा भेजने की परफ़ॉर्मेंस काफ़ी बेहतर हो जाती है. अगर आप C/C++ दुनिया से हैं, तो इसे पास-दर-रेफ़रंस के तौर पर देखें. हालांकि, पास-बाय-रेफ़रंस के उलट, नए कॉन्टेक्स्ट में ट्रांसफ़र करने के बाद, कॉल करने के कॉन्टेक्स्ट का 'वर्शन' उपलब्ध नहीं होता. उदाहरण के लिए, किसी ArrayBuffer को अपने मुख्य ऐप्लिकेशन से वर्कर पर ट्रांसफ़र करते समय, मूल ArrayBuffer हटा दिया जाता है और अब इस्तेमाल नहीं किया जा सकता. इसकी सामग्री को (शाब्दिक रूप से) वर्कर के संदर्भ में ट्रांसफ़र कर दिया जाता है.

ट्रांसफ़र किए जा सकने वाले ऑब्जेक्ट के साथ खेलने के लिए, postMessage() का एक नया वर्शन उपलब्ध है. इसमें ऐसे ऑब्जेक्ट हैं जिन्हें ट्रांसफ़र किया जा सकता है:

worker.postMessage(arrayBuffer, [transferableList]);
window.postMessage(arrayBuffer, targetOrigin, [transferableList]);

वर्कर के मामले में, पहला तर्क ArrayBuffer मैसेज होता है. दूसरा तर्क, उन आइटम की सूची होता है जिन्हें ट्रांसफ़र किया जाना चाहिए. इस उदाहरण में, आप ट्रांसफ़रेबल सूची में arrayBuffer के बारे में बताएंगे.

बेंचमार्क डेमो

ट्रांसफ़र किए जा सकने वाले डिवाइसों की परफ़ॉर्मेंस के बारे में जानने के लिए, मैंने एक डेमो तैयार किया है.

डेमो, किसी वर्कर को 32 एमबी की ArrayBuffer फ़ाइल और postMessage() का इस्तेमाल करके वापस भेजता है. अगर आपके ब्राउज़र में ट्रांसफ़र किए जा सकने वाले आइटम काम नहीं करते हैं, तो सैंपल स्ट्रक्चर्ड क्लोनिंग के तौर पर इस्तेमाल किया जाएगा. अलग-अलग ब्राउज़र में औसतन पांच बार चलाने पर, मुझे यह जानकारी मिली:

स्ट्रक्चर्ड क्लोनिंग और ट्रांसफ़र किए जा सकने वाले ऑब्जेक्ट की तुलना करने वाला चार्ट

MacBook Pro/10.6.8/2.53 GHz/Intel Core 2 Duo पर, FF स्ट्रक्चर्ड क्लोनिंग का सबसे तेज़ इस्तेमाल किया जाता है. किसी वर्कर को 32 एमबी ArrayBuffer भेजने और उसे मुख्य थ्रेड (आरआरटी - दोतरफ़ा यात्रा का समय) पर वापस पोस्ट करने में औसतन 302 मिलीसेकंड लगे. ट्रांसफ़र किए जा सकने वाले डेटा की तुलना में, इस टेस्ट में 6.6 मिलीसेकंड लगे. यह बहुत बढ़िया परफ़ बूस्ट है!

इस तरह की स्पीड होने से, WebGL टेक्सचर/मेश को वर्कर और मुख्य ऐप्लिकेशन के बीच आसानी से पास किया जा सकता है.

फ़ीचर का पता लगाने की सुविधा

इसके साथ सुविधा का पता लगाना थोड़ा मुश्किल है. मेरा सुझाव है कि आप अपने वर्कर को एक छोटा ArrayBuffer भेजें. अगर बफ़र को ट्रांसफ़र किया जाता है और कॉपी नहीं किया जाता है, तो इसका .byteLength 0 पर जाएगा:

var ab = new ArrayBuffer(1);
worker.postMessage(ab, [ab]);
if (ab.byteLength) {
    alert('Transferables are not supported in your browser!');
} else {
    // Transferables are supported.
}

सहायता: फ़िलहाल, Chrome 17+, Firefox, Opera, Safari, और IE10+

अपडेट किया गया (13-12-2011): विंडो और वर्कर के लिए, webkitPostMessage() हस्ताक्षर दिखाने वाला कोड स्निपेट अलग-अलग है. अपडेट किया गया (2016-11-03): वेंडर प्रीफ़िक्स और अपडेट किए गए कोड स्निपेट हटाए गए