Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

مقایسه عملکرد: حلقه‌ها در برابر Iteratorها

برای تعیین اینکه از حلقه‌ها یا iteratorها استفاده کنید، باید بدانید کدام پیاده‌سازی سریع‌تر است: نسخه تابع search با حلقه صریح for یا نسخه با iteratorها.

ما یک بنچمارک اجرا کردیم که در آن تمام محتوای کتاب The Adventures of Sherlock Holmes اثر سر آرتور کانن دویل را در یک String بارگذاری کردیم و به دنبال کلمه the در محتوا گشتیم. نتایج بنچمارک برای نسخه search با استفاده از حلقه for و نسخه با iteratorها به شرح زیر است:

test bench_search_for  ... bench:  19,620,300 ns/iter (+/- 915,700)
test bench_search_iter ... bench:  19,234,900 ns/iter (+/- 657,200)

دو پیاده‌سازی عملکرد مشابهی دارند! ما کد بنچمارک (benchmark) را اینجا توضیح نمی‌دهیم، زیرا هدف این نیست که ثابت کنیم این دو نسخه معادل هستند، بلکه هدف این است که به یک درک کلی از نحوه مقایسه عملکردی این دو پیاده‌سازی برسیم.

برای یک بنچمارک جامع‌تر، باید از متن‌های مختلف با اندازه‌های گوناگون به‌عنوان contents، کلمات مختلف و کلماتی با طول‌های متفاوت به‌عنوان query، و انواع دیگری از تغییرات استفاده کنید. نکته این است: iteratorها، اگرچه یک انتزاع سطح بالا هستند، به کدی که تقریباً همان سطح پایینی دارد کامپایل می‌شوند، انگار خودتان کد سطح پایین را نوشته باشید. iteratorها یکی از انتزاع‌های بدون هزینه Rust هستند، به این معنی که استفاده از انتزاع هیچ هزینه اضافی زمان اجرای برنامه را تحمیل نمی‌کند. این موضوع مشابه تعریفی است که بیارنه استراس‌تروپ، طراح و پیاده‌ساز اصلی ++C، در مقاله “Foundations of C++” (2012) برای بدون هزینه اضافی ارائه می‌دهد:

به طور کلی، پیاده‌سازی‌های ++C از اصل بدون هزینه اضافی پیروی می‌کنند: چیزی که استفاده نمی‌کنید، هزینه‌ای برای شما ندارد. و علاوه بر این: چیزی که استفاده می‌کنید، نمی‌توانید بهتر از این دستی کدنویسی کنید.

در بسیاری از موارد، کدی که در Rust با استفاده از پیمایشگرها نوشته می‌شود، به همان کدی در اسمبلی کامپایل می‌شود که اگر دستی می‌نوشتید تولید می‌شد. بهینه‌سازی‌هایی مانند بازگشایی حلقه‌ها (loop unrolling) و حذف بررسی محدوده (bounds checking) در دسترسی به آرایه‌ها اعمال می‌شوند و کد نهایی را بسیار بهینه می‌سازند. اکنون که این را می‌دانید، می‌توانید با خیال راحت از پیمایشگرها و closures استفاده کنید! آن‌ها باعث می‌شوند کد سطح بالاتری به نظر برسد، اما هیچ جریمه‌ای از نظر عملکرد در زمان اجرا به همراه ندارند.

خلاصه

closureها و iteratorها ویژگی‌های Rust هستند که از ایده‌های زبان‌های برنامه‌نویسی تابعی الهام گرفته‌اند. آن‌ها به توانایی Rust در بیان واضح ایده‌های سطح بالا با عملکرد سطح پایین کمک می‌کنند. پیاده‌سازی closureها و iteratorها به گونه‌ای است که عملکرد زمان اجرا تحت تأثیر قرار نمی‌گیرد. این بخشی از هدف Rust برای ارائه انتزاع‌های بدون هزینه است.

اکنون که قابلیت بیان پروژه I/O خود را بهبود داده‌ایم، بیایید نگاهی به برخی ویژگی‌های بیشتر cargo بیندازیم که به ما کمک می‌کنند پروژه را با دنیا به اشتراک بگذاریم.