کدام کدها بهینهتر هستند؟
یکی از موارد مهم در دنیای برنامهنویسی این است که بدانیم قطعه کدهای مختلف با چه سرعتی اجرا میشوند و برای ما بهتر است که در کجا از کدام ساختار استفاده کنیم.
بدون مقدمه وارد بحث شویم. در این مقاله با استفاده از زبان برنامهنویسی سیشارپ برخي از این نکات به شما آموزش داده شده است. در ابتدا برای راحتی کار و دوری از محیط گرافیکی، یک برنامه کنسول را اجرا میکنیم.
انتخاب نوع داده
اولین مبحثی که میخواهیم به شما بگوییم این است که سعی کنید نوع دادهی خود را همان ابتدا معین کنید ممکن است بگویید چرا؟ در ادامه متوجه میشوید که این کار سرعت بالاتری دارد. برای اثبات این کار مراحل زیر را دنبال کنید:
1- فضای نام زیر را به برنامه اضافه کنید (کاری با دیگر فضای نام های پیشفرض نداشته باشید):
دقت داشته باشید که چون میخواهیم سرعت اجرای کدها را ببینیم به کلاس Stopwatch نیاز داریم که در فضای نام بالا است خیلی ساده بخواهیم بگوییم از این کلاس میتوانیم شیء تعریف کنیم و بعد به آن بگوییم که فلان کد چقدر زمان برده است تا اجرا شود! به همین راحتی ؛
2- ابتدا یک لیست از نوع int تعریف میکنیم و سپس یک Instance از کلاس Stopwatch درست میکنیم. سپس آن Instance را اجرا میکنیم و در یک حلقهی For به تعداد 10 هزار مرتبه به خانههای آن آرایه مقدار میدهیم و سپس Instance را متوقف میکنیم. (هر کدی که مابین شروع و پایان Instance بوده مبنای محاسبه تعداد تیکهای صرف شده در مکانیزم شمارنده هست). این کار را بار بعدی برای یک آرایه از نوع int تکرار میکنیم.
با اجرای کد بالا ملاحظه میکنید که سرعت اجرای کد در زمانی که نوع داده معین است بالاتر میباشد.
چرا این اختلاف وجود دارد؟
دلیل این امر این است که لیست داده ها را در قالب شی ذخیره می کند و هنگامی که می خواهیم value type را ذخیره کنیم آن را به reference type تبدیل می کند، سپس ذخیره می شود. بنابراین نکته مهم اين است که همیشه مکانیزم ذخیره سازی مناسب را انتخاب کنید تا بهترین عملکرد را داشته باشید.
پس یعنی همیشه از آرایه استفاده کنیم؟
خیر! شما میدانید که آرایه دارای ظرفیت رزرو شده است چه شما از خانههای آن استفاده کنید چه خیر اما به یاد داشته باشید که اگر هیچ زمانی نیاز به متدهای یک لیست ندارید این کار را انجام ندهید.
استفاده کردن از For loop به جای foreach
خیلی از شما ممکن است این را از قبل میدانستید که for سریع تر از foreach است. به برنامه زیر دقت داشته باشید در ابتدا سه لیست تعریف کردهایم و لیست اول را مقداردهی کردهایم سپس دومین لیست را با استفاده از for و سومین لیست را نیز با استفاده از foreach از مقادیر لیست اول پر کردهایم.
زمانی که برنامه را اجرا کنیم میبینیم که for سریع تر بوده است.
بدانید کجا Struct و کجا Classها بهتر هستند
اگر شما هم فکر میکنید که خوب من با Struct ها کار کردم اما هیچ زمانی از آنها استفاده نکردهام، شاید در ادامه نظرتان عوض شود!
در برنامه در فضای نام ابتدا یک Struct و سپس یک Class نوشته شده است که هر کدام دو پراپرتی نیز دارند در ادامه هر کدام از کلاس ها به همراه پراپرتیهای خودشان هزار مرتبه مقدار دهی شده اند.
پس از اجرای برنامه خواهید دید که سرعت struct بالاتر است.
و اما چرا؟
احتمالاً همهی شما عزیزان میدانید که در یک جمله کوتاه struct همان کلاسها هستند که ساختار کوتاه تری دارند اما این تمام ماجرا نیست. struct ساختاری value type دارد در صورتی که classها reference type هستند بدین معنی که اشارهگر کلاس ساخته میشود اما محتوای کلاس در جای دیگری هستند. به بیانی دیگر اساساً مقدار در یک پشته قابل کنترل ذخیره می شود و نشانگر در Stack ایجاد می شود.
آیا همیشه از struct ها استفاده کنیم؟
خیر! ببینید struct ها ساختاری کوتاه تر و مختصر تر هستند طبیعتاً اگر به نظر میرسد یک کلاس در یک struct میتواند ساخته شود (با در نظر گرفتن همهی جوانب) پس شاید این کار بهتر و البته بهینه تر باشد.
از Stringbuilder برای الحاق رشتهها استفاده کنید
یکی از راههای بهتر برای الحاق رشتهها استفاده کردن از StringBuilder است به برنامه زیر دقت کنید:
در برنامهی زیر ابتدا یک رشته را تعریف کردهایم و سپس 500 مرتبه آن را بعلاوه یک رشته دیگر کردهایم. ممکن است از دیدن تفاوت سرعت اجرای StringBuilder با زمانی که یک رشته را با بعلاوه به یک رشته دیگر الحاق میکنیم، شما را متعجب کند!
به تفاوت سرعت کدها دقت کنید:
بهترین راه را برای مقداردهی به متغیرها انتخاب کنید
استفاده کردن از فیلد و پراپرتی در کلاسها عمدتاً یک باید است اما شاید بهتر باشد بدانیم کدامیک سریع تر میباشد. شاید باعث شود از تعریف بیهوده و بدون توجیه فیلد خودداری کنیم.
به برنامه زیر دقت کنید که یک کلاس با یک متغیر و یک فیلد تعریف کردهایم (برای جلوگیری از ساخت شیء از کلاس، پراپرتیها بصورت استاتیک هستند).
هنگامی که برنامه را اجرا کنیم تفاوت سرعت را متوجه میشویم:
دقت داشته باشید که زمانی که یک متغیر را مستقیم مقداردهی میکنیم سرعت بسیار بالاتر از زمانی است که از پراپرتی استفاده کردهایم. این نکته خوب است اما یک زنگ خطر نیز میباشد که تنها در صورتی به کلاسهای تابعه اجازه دهید که این مقادیر را مستقیم مقدار دهی کنند که واقعاً نیاز باشد در غیر اینصورت عدم استفاده از پراپرتی میتواند به ضرر امنیت دادههای برنامه باشد.
یک نکته مهم
هیچ زمانی کارایی و امنیت برنامه را فدای سرعت نباید کرد اما این جمله اصلاً به معنی رعایت نکردن اصول و معماریهای پیشنهاد شده برای ساخت برنامهها نمیباشد. گاهی شما کدهای بیشتری مینویسید اما امنیت و سرعت حفظ میشود گاهی هم فقط سرعت بالاتر میروند که مورد آخر خوب نیست. جدای از همهی اینها اگر زمانی بدون توجه به قابلیتهای یک متد یا کلاً یک ساختار و قطعه کد در برنامهنويسی اقدام به بکارگیری آن میکنید حتماً داكيومنتهاي آن مطالعه كنيد و مزايا و معايب آن را متوجه شويد و صد البته ببينيد كه كارايي و سرعت كداميك بهتر و بهينه تر است.
نظرات کاربران در رابطه با این دوره