اشیاء قابل انتقال - رعد و برق سریع

Chrome 13 ارسال ArrayBuffer s به/از Web Worker را با استفاده از الگوریتمی به نام شبیه سازی ساختاریافته معرفی کرد. این به API postMessage() اجازه می‌دهد پیام‌هایی را بپذیرد که فقط رشته‌ها نیستند، بلکه انواع پیچیده‌ای مانند اشیاء File ، Blob ، ArrayBuffer و JSON هستند. شبیه سازی ساختاریافته در نسخه های بعدی فایرفاکس نیز پشتیبانی می شود.

سریعتر بهتر است

شبیه سازی ساختاریافته عالی است، اما همچنان یک عملیات کپی است. سربار ارسال یک ArrayBuffer 32MB به یک Worker می تواند صدها میلی ثانیه باشد. نسخه‌های جدید مرورگرها دارای یک بهبود عملکرد بزرگ برای ارسال پیام هستند که اشیاء قابل انتقال نام دارد.

با اشیاء قابل انتقال، داده ها از یک زمینه به زمینه دیگر منتقل می شوند. کپی صفر است که عملکرد ارسال داده ها به Worker را بسیار بهبود می بخشد. اگر اهل دنیای C/C++ هستید، آن را به عنوان یک مرجع گذرا در نظر بگیرید. با این حال، برخلاف مرجع گذرا، «نسخه» از زمینه فراخوانی پس از انتقال به زمینه جدید دیگر در دسترس نیست. به عنوان مثال، هنگام انتقال یک ArrayBuffer از برنامه اصلی خود به Worker، ArrayBuffer اصلی پاک می شود و دیگر قابل استفاده نیست. محتویات آن (به معنای واقعی کلمه آرام) به بافت کارگر منتقل می شود.

برای بازی با قابل انتقال، نسخه جدیدی از postMessage() وجود دارد که از اشیاء قابل انتقال پشتیبانی می کند:

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

برای مورد کارگر، اولین آرگومان پیام ArrayBuffer است. آرگومان دوم لیستی از مواردی است که باید منتقل شوند. در این مثال، شما باید arrayBuffer را در لیست قابل انتقال مشخص کنید.

نسخه ی نمایشی معیار

برای دیدن دستاوردهای عملکرد قابل انتقال، من یک نسخه نمایشی را جمع آوری کرده ام.

نسخه ی نمایشی یک ArrayBuffer 32 مگابایتی را برای یک کارگر ارسال می کند و با استفاده از postMessage() برمی گردد. اگر مرورگر شما قابلیت انتقال را پشتیبانی نمی‌کند، نمونه به شبیه‌سازی ساختاریافته بازمی‌گردد. به طور متوسط ​​5 اجرا در مرورگرهای مختلف، این چیزی است که من دریافت کردم:

نمودار مقایسه شبیه سازی ساختاریافته در مقابل اشیاء قابل انتقال

در MacBook Pro/10.6.8/2.53 گیگاهرتز/Intel Core 2 Duo، FF سریع‌ترین با استفاده از شبیه‌سازی ساختاریافته بود. به طور متوسط، ارسال ArrayBuffer 32 مگابایتی به یک کارگر و ارسال آن به موضوع اصلی (RRT - زمان رفت و برگشت) به طور متوسط ​​302 میلی ثانیه طول کشید. در مقایسه با موارد قابل انتقال، همان آزمایش 6.6 میلی‌ثانیه طول کشید. این یک افزایش عملکرد بزرگ است!

داشتن این نوع سرعت‌ها باعث می‌شود بافت‌ها/مش‌های عظیم WebGL به طور یکپارچه بین Worker و برنامه اصلی منتقل شوند.

تشخیص ویژگی

تشخیص ویژگی با این یکی کمی مشکل است. توصیه من این است که یک 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() برای پنجره و کارگر متفاوت است. به روز شده (03/11/2016): پیشوندهای فروشنده و قطعه کد به روز شده حذف شدند