آیا نوشتن صریح برخی دستورات باعث افزایش سرعت اجرای کد میشه؟ - هفت خط کد انجمن پرسش و پاسخ برنامه نویسی

آیا نوشتن صریح برخی دستورات باعث افزایش سرعت اجرای کد میشه؟

0 امتیاز

سلام

برای مثال زمانی که دستور چاپ رو همراه با متد ToString مینویسم آیا از دستور چاپی که بدون متد ToString نوشته میشه سرعت اجراش بیشتره؟

System.Console.Write(value.ToString());  //متد تو استرینگ صریح نوشته شده
System.Console.Write(value);             //متد تو استرینگ نوشته نشده

 

سوال شده مهر 6, 1393  بوسیله ی امیدوار (امتیاز 872)   21 63 76
دوباره تگ گذاری شد مهر 9, 1393 بوسیله ی BlueBlade

1 پاسخ

+2 امتیاز
 
بهترین پاسخ
برای نوشتن داخل کنسول عمده زمان صرف همون نوشتن میشه و اون تبدیل (ToString) زمان خیلی  خیلی کم و جزیی می گیره پس میشه از تاثیرش صرف نظر کرد .

بعد سوالتون هم بستگی به پیاده سازی Write در #C داره شاید value هم داخل روش دوم قبل از چاپ به String تبدیل بشه که در این صورت تفاوتی ندارند .
پاسخ داده شده مهر 6, 1393 بوسیله ی BlueBlade (امتیاز 15,315)   15 18 89
انتخاب شد مهر 9, 1393 بوسیله ی امیدوار
سلام، برای اندازه گیری زمان سرعت اجرای برنامه از کلاس Stopwatch استفاده کردم، سرعت اجرای برنامه در حالت اول(کد صریح) بیشتراز حالت دوم بود، در صورتی که زمان کامپایل برنامه در حالت اول بسیار بیشتر از حالت دوم بود.
کدوم کد میتونه مناسب تر باشه؟  بحث حافظه هم باید مد نظر باشه آیا این دو حالت فضای حافظه با حجم متفاوتی به خودشون اختصاص میدن؟
در حالت دوم فضای نام system رو به صورت using تعریف کردم.
من متد Wrtie سی شارپ رو با redgate reflector نگا کردم اینجور کدی دارن :
برای String:
 
       [__DynamicallyInvokable]
        public virtual void Write(string value)
        {
            if (value != null)
            {
                this.Write(value.ToCharArray());
            }
        }


و برای int هم از این تابع استفاده میشه :
        [__DynamicallyInvokable]
        public virtual void Write(int value)
        {
            this.Write(value.ToString(this.FormatProvider));
        }

مورد دوم داخل خود تابع ToString رو صدا میزنه بعد هم تابع اول رو صدا میزنه .
حالا مورد اول این ToString صدا زدن بیرون از تابع انجام  میشه.
پس فرقی با هم ندارن.

ضمنا زمانی هم که با StopWatch میگیرید به خیلی چیز های دیگه هم ممکنه ربط داشته باشه مثلا به garbage collector به فعال بودن cpu به زمان پاسخ دهی cpu به interupt برای نوشتن و نجوه کار کامپایلر JIT در اون کد خاص , ...
پس دقیق و درست نیست .
راستی زمان کامپایل رو چطور اندازه گرفتید ؟
بعد هم این که اصولا این جور موارد اکثر اوقات  در سرعت فایل خروجی پایانی تاثیر خاصی هم نمیزارن  .
مطالب این لینک رو بخونید :http://programmers.stackexchange.com/questions/99445/is-micro-optimisation-important-when-coding
در کل هم همون روش دوم بهتر هست چون وقتی که نیاز به تبدیل به String نیست پس نباید از اون تابع استفاده کنید و به String تبدیل کنید چون ممکنه که اون تابع خاص برای کار کردن با int بهینه شده باشه و کاملا متد int با String تفاوت داشته باشه (البته برای Write طبق اون کدی که بالا گذاشتم تفاوتی نداره)
وقتی که برنامه رو debug میکردم، تو خروجی محیط کنسول مکان نما توقف متفاوتی رو داشت مثلا برای اجرای یه برنامه 23 ثانیه توقف داشت  و برای اجرای برنامه دیگه 2 ثانیه! احتمال دادم که کامپایلر داره کدها رو کامپایل میکنه و برنامه اماده اجرا میشه.
بعد از شروع چاپ مقادیری که کدش رو نوشته بودم، کلاس StopWatch شروع میکرد به اندازه گیری زمان، و زمان وقفه مکان نما رو حساب نمیکرد!.
کدها رو هم خیلی زیاد نوشته بودم برای اینکه تفاوت زمانیشون بسیار مشهود باشه.
50000 خط دستور System.Console.Write(i.ToString) رو نوشته بودم:) که توی این برنامه مکان نما 22 تا 23 ثانیه حداقل توقفش بود و کمترین زمان رو بر حسب ثانیه 2.47  ثانیه اندازه گیری کردم.
50000 خط هم دستور Console.WriteLine(i) رو نوشته بودم:) که توی این برنامه مکان نما حداکثر 2 ثانیه توقف میکرد و کمترین زمان رو بر حسب ثانیه ، از7 ثانیه کمی بیشتر اندازه گیری کردم.
پشت سر هم دیباگ میکردم مثلا وقتی که توی حالت اول دیباگ میکردم بهم زمان 2 الی 3 یا 4 ثانیه رو نشون میداد و بعدش که حالت دوم رو دیباگ میکردم زمان 10 الی 12 ثانیه رو بهم نشون میداد .
حتی فایل exe رو هم از پوشه ای که فایلهای برنامه تو اون قرار داشت رو حذف کردم و مجددا امتحان کردم اما باز هم همون نتیجه رو میگرفتم.
ولی در کل من  زمانی رو نتونستم اندازه گیری کنم که این کد => Console.WriteLine(i) زمان اجراش کمتر از این کد => System.Console.WriteLine(i.ToString) باشه.
برای تست کردن سرعت برنامه باید از مد release استفاده کنید نه debug .
کدتون رو هم اگر خیلی طولانی هست یکجا آپلود کنید بزارید ؟
من این کد رو تست کردم فرقی نداشتن (البته حالت دوم یک مقدار خیلی جزیی سریع تر هم هست )
using System;
using System.Diagnostics;
namespace ConsoleApplication3
{
     class Program
     {
          static void Main(string[] args)
          {
               Stopwatch watch = new Stopwatch();
               long time1, time2;

               watch.Start();
               for (int i = 0; i < 50000; i++)
                    Console.Write(i.ToString());
               watch.Stop();
               time1 = watch.ElapsedMilliseconds;

               watch.Reset();

               watch.Start();
               for (int i = 0; i < 50000; i++)
                    Console.Write(i);
               watch.Stop();
               time2 = watch.ElapsedMilliseconds;

               Console.WriteLine("\n" + time1+" "+time2);
          }
     }
}

خیلی ممنون
 جای دستور حلقه ها رو عوض کردم  در هر صورت حلقه دوم سریع تر از حلقه اول اجرا میشه.
احتمالا بخاطراین هست که اعداد 1 تا 50000 بعد از for اول چون داخل cache  سی پی یو ذخیره شدن حلقه دوم سریع تر انجام میشه ... یا شاید هم garbage collector داره چیزیو پاک می کنه. بالاتر هم گفتم زمانی که timer میده مطالب زیادی داخلش دخیل هستند
چون که داخل #C بر خلاف ++C به کد اسمبلی که تولید میشه دسترسی نمیشه داشت دقیق نمیشه فهمید بخاطر چی هست .
for ها رو داخل 2 تا برنامه جدا بنویسید و اجرا کنید زمان تقریبا یکسان هست که با توجه به نحوه پیاده سازی  write و writeLine که داخل کامنت اول گذاشتم کاملا طبیعی هم هست
تشکر بابت پاسختون، رسیدن به یک نتیجه مشخص برام خیلی اهمیت داشت
...