مقایسه عملکرد: حلقهها در برابر 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 استفاده کنید! آنها باعث میشوند کد سطح بالاتری به نظر برسد، اما هیچ جریمهای از نظر عملکرد در زمان اجرا به همراه ندارند.
خلاصه
اکنون که قابلیت بیان پروژه I/O خود را بهبود دادهایم، بیایید نگاهی به برخی ویژگیهای بیشتر cargo
بیندازیم که به ما کمک میکنند پروژه را با دنیا به اشتراک بگذاریم.