‌وب‌اسمبلی چیست و چرا این روزها محبوب شده است؟
 وب‌اسمبلی، فناوری رقیب جاوااسکریپت
وب‌اسمبلی به عنوان فناوری رقیب جاوااسکریپت و برای حل مشکلاتی که جاوااسکریپت قادر به حل آن‌ها نبود ابداع شد. وب‌اسمبلی (WASM) یک فرمت دستوری دودویی است که برای ماشین مجازی مبتنی بر پشته استفاده می‌شود. وب‌اسمبلی به توسعه‌دهندگان اجازه می‌دهد تا برنامه‌های کلاینت و سرور را روی وب توسعه دهند. در این مطلب قصد داریم به شکل اجمالی فناوری فوق را بررسی کنیم و الگوریتمی طراحی کردیم که اجازه می‌دهد WASM و Vanilla JS را با یکدیگر مقایسه کنید.

برای آن‌که بتوان عملکردهای هر دو فناوری را به بهترین شکل بررسی کرد، باید در قالب یک مثال عملی به تشریح این مسئله پرداخت. به همین دلیل به سراغ بازی Game of Life رفتیم که شرکت Conway آن‌را طراحی کرده است. بازی فوق دستورالعمل ساده‌ای دارد و هیچ بازیکنی ندارد. در این بازی جهانی بر مبنای یک ماتریس طراحی شده که هر سلول دو حالت زنده یا مرده را دارد. تنها ورودی بیرونی آن، حالت اولیه است، ارتباط سلول زنده با سلول افقی، عمودی و قطری وضعیت جاری سلول را مشخص می‌کند، سلولی که کمتر از دو همسایه مجاور آن زنده باشند خواهد مرد، سلولی که دو یا سه همسایه زنده داشته باشد، نسل بعدی آن زنده می‌ماند، سلول زنده که بیش از سه سلول همسایه‌اش زنده باشد خواهد مرد و یک سلول مرده که سه سلول همسایه‌اش زنده باشد، زنده باقی می‌ماند. در طرحی که قصد پیاده‌سازی آن‌را داریم یک ماتریس بزرگ داریم و قرار است با مقادیر 0 و 1 آن‌را پر کنیم، حالت اولریه را ارسال می‌کنیم و نتیجه را پردازش می‌کنیم، در ادامه حالت بعدی را محاسبه کرده و دومرتبه نتیجه را پردازش می‌کنیم. آخرین مرحله را چند مرتبه تکرار می‌کنیم.  در نظر داریم طرح خود را با سه سناریو مختلف جاوااسکریپت عادی، وب‌اسمبلی و وب‌ورکرها پیاده‌سازی کنیم.پیچیدگی زمانی الگوریتم ما برابر با مقدار نمایی O(n*m) است که n عرض جهان و m ارتفاع آن است.

جاوااسکریپت عادی

معماری زیربنایی طرح ما بر ساخت یک بازی جدید و ایجاد و ارسال حالت اولیه (ماترسی که با 0 و 1 پر شده) است. مولفه gane وضعیت را نگه‌داری می‌کند و تابع next حالت بعدی در زمان فراخوانی بازگشتی را بر می‌گرداند. در زمان بازگشت تابع getNextState() از فایل environment.js فراخوانی می‌شود که یک پیاده‌سازی از Vanilla JS است.

...

const next = game(
  document.getElementById('game'),
  COLUMNS,
  LINES,
  createGameMatrix(LINES, COLUMNS), // generates the initial state
  strategy(
    STRATEGY,
    COLUMNS,
    LINES,
    initialConfig
  ) // Defines which strategy to use to calculate the next state
);

...

function loop() {
  next().then(() => {
    requestAnimationFrame(loop);
  });
};

loop();

درون مولفه envirtoment.js مشکل را به توابع تخصصی کوچک‌تر شکستیم تا کامپایلر JIT مرورگر به شکل ساده‌تر و بهینه‌تری بتواند کدها را کامپایل کند. توابع فوق حالت‌های کنونی همسایه‌های فوقانی، تحتانی و کناری را ارزیابی کرده و تمامی حالت‌های کناری را پوشش می‌دهد.

همان‌گونه که در شکل بالا مشاهده می‌کنید، میانگین سرعت محاسبه حالت فوق در بازه 4 تا 9 میلی‌ثانیه برای ماتریسی در ابعاد 450 در 800 متغیر است.

تاریخچه‌ای از جاوااسکریپت

جاوااسکریپت در سال 1995 میلادی توسط برندن آیک طراحی شد. این توسعه‌دهنه بزرگ در نظر داشت به طراحان کمک کند تا رابط‌های پویا را به ساده‌ترین شکل ممکن پیاده‌سازی کنند. به عبارت دیگر، جاوااسکریپت برای اجرای سریع طراحی نشد، بلکه هدف پیاده‌سازی یک لایه اضافی برای صفحات THML بود که امکان پیاده‌سازی رفتارهای پویا به شکل ساده‌تر و راحت‌تری انجام شود. در زمان شکل‌گیری جاوااسکریپت اینترنت همانند تصویر زیر بود:

جاوااسکریپت در ابتدا یک زبان تفسیری بود و به همین دلیل فاز اولیه سریع‌تر اجرا می‌شد، زیرا مفسر تنها می‌بایست خط اول را بخواند تا بتواند آن‌را به بایت‌کد ترجمه و به شکل درستی اجرا کند. در دهه 90 میلادی جاوااسکریپت در ارتباط با صفحات وبی که پیچیدگی خاصی نداشتند عملکرد عالی داشت، اما به تدریج برنامه‌های تحت وب شکل پیچیده‌تری به خود گرفتند. در اوایل سال 2000 میلادی فناوری‌هایی همچون Ajax پویایی خاصی به برنامه‌های تحت وب بخشیند، جیمیل در سال 2004 میلادی و گوگل مپ در سال 2005 میلادی اصلی‌ترین عواملی بودند که به فراگیری Ajax کمک کردند. روش نوین طراحی صفحات وب باعث شد که بخش عمده‌ای از منطق برنامه در سمت کلاینت نوشته شود. به موازات این پیشرفت‌ها، جاوااسکریپت نیز توسعه پیدا کرد تا این‌که در سال 2008 میلادی با عرضه موتور V8 که تمامی کدهای جاوااسکریپت را به شکل آنی به بایت‌کد کامپایل می‌کرد عصر جدیدی برای جاوااسکریپت رقم خورد.

کامپایلرهای JIT چگونه کار می‌کنند؟

عملکرد کامپایلر JIT به این شکل است که زمانی که کد بارگذاری می‌شود، کد منبع به ماهیتی درختی تبدیل می‌شود که به آن درخت ساختار مجرد (AST) سرنام Abstract Syntax Tree می‌گویند. در ادامه بسته به زیرساختی که کامپایلر روی آن اجرا می‌شود یک نسخه پایه از کد کامپایل شده یا بایت‌کد ساخته شده تفسیر می‌شود. در مرحله فوق profiler داده‌های اجرای کد را جمع‌آوری می‌کند. در اولین گام همه چیز از فیلتر مفسر عبور می‌کند، فرآیند فوق ضمانت می‌دهد که کد پس از ایجاد درخت ساختار مجرد به شکل سریع‌تری اجرا می‌شود.

کامپایلر مبنا

برای آن‌که با شیوه کارکرد JIT بهتر آشنا شوید به مثال زیر دقت کنید:

function sum (x, y) {   return x + y; }[1, 2, 3, 4, 5, '6', 7, 8, 9, 10].reduce(   (prev, curr) => sum(prev, curr),   0 );

زمانی که پروفایلر قطعه کدی را به شکل کد گرم (code as warm) نشانه‌گذاری می‌کند، JIT کد را به سمت کامپایلر مبنا هدایت می‌کند تا یک کد کامپایل شده ایجاد کند. در همین زمان پروفایلر داده‌هایی در ارتباط با فراوانی و انواع کدهایی که در حال اجرا است جمع‌آوری می‌کند.

کامپایلر بهینه‌کننده

زمانی‌که قطعه کدی تحت عنوان کد مهم (کد گرم)  نشانه‌گذاری می‌شود، کامپایلر بهینه‌کننده سعی می‌کند نسخه‌ای بهینه شده از کد را تولید کند. در این حالت کامپایلر بهینه کننده سعی می‌کند، نوع متغیرها و نمونه‌های تولید شده از اشیا استفاده شده در کدها را بهینه کند. به‌طور مثال، در مثالی همچون return x+ y کامپایلر فرض می‌کند که هر دو متغیر x  و y از نوع عددی هستند. با این حال، در برخی موارد کامپایلر بهینه کننده یا دستوراتی روبرو می‌شود که انتظار دریافت آن‌ها را ندارد. به‌طور مثال تابعی همچون sum(15, ‘6’)  را تصور کنید که متغیر y از نوع رشته‌ای است. زمانی که چنین حالتی روی می‌دهد، پروفایلر تصور می‌کند که فرضیات اشتباه بوده و به سراغ نسخه کامپایل شده اصلی بر می‌گردد. مرحله فوق بهینه‌سازی نشده (Deoptimization) نام دارد. اگر این مشکل به‌طور مکرر رخ دهد باعث می‌شود که سرعت نسخه بهینه شده از نسخه اصلی کمتر شود.

برخی از موتورهای جاوااسکریپت در ارتباط با بحث بهینه‌سازی با محدودیت‌هایی روبرو هستند و زمانی که متوجه شوند بهینه‌سازی سودی ندارد، ادامه کار را متوقف می‌کنند. برخی از این موتورهای جست‌وجو شبیه به V8 زمانی که به شکل روشنی متوجه شوند که کد غیر بهینه شده‌ای تولید خواهد شد از ادامه کار صرفنظر می‌کنند. رویکردی که bailing out نام دارد. در مجموع مراحل کامپایلر JIT را می‌توان تجزیه، کامپایل، بهینه‌سازی /یا غیر بهینه‌سازی، اجرا و Garbage Collector (جمع‌آوری اشیا بلااستفاده از حافظه اصلی) تشریح کرد:

‌پیشرفت‌های انجام شده در ارتباط با کامپایلرهای JIT باعث شده تا جاوااسکریپت در مقایسه با سال 2008 میلادی عملکرد سریع‌تر و بهتری پیدا کند. برنامه‌های کاربردی امروزی به واسطه سرعت خوب موتورهای جاوااسکریپت عملکردی سریع‌تر و پایدارتر پیدا کرده‌اند.


ماهنامه شبکه را از کجا تهیه کنیم؟
ماهنامه شبکه را می‌توانید از کتابخانه‌های عمومی سراسر کشور و نیز از دکه‌های روزنامه‌فروشی تهیه نمائید.

ثبت اشتراک نسخه کاغذی ماهنامه شبکه         ثبت اشتراک نسخه  آنلاین 

کتاب الکترونیک +Network راهنمای شبکه‌ها

  • برای دانلود تنها کتاب کامل ترجمه فارسی +Network اینجا کلیک کنید.

کتاب الکترونیک دوره مقدماتی آموزش پایتون

  • اگر قصد یادگیری برنامه‌نویسی را دارید ولی هیچ پیش‌زمینه‌ای ندارید اینجا کلیک کنید.

برچسب: 

مطالب پربازدید

توسعه و پشتیبانی توسط : ایران دروپال
پشتیبانی توسط ایران دروپال