ده تکنیک افزایش سرعت اجرای برنامه های دات نت

پرووید

دسته های مقالات

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

دات نت فریم ورک چیست؟

دات نت فریم ورک یک پلتفرم است که با استفاده از آن می توانیم انواع مختلفی از اپلیکیشن های تحت وب و یا تحت ویندوز را ایجاد کنیم. برنامه هایی که یا در بستر وب اجرا میشوند یا به صورت دسکتاپ اجرا می‌شود. برای استفاده از دات نت فریم ورک ما نیاز به یک زبان برنامه نویسی از قبیل سی شارپ، ویژوال بیسیک، F# یا غیر داریم. زبان F# بیشتر برای ساخت برنامه های تابع گرا استفاده می شود. در رابطه با برنامه نویسی تابعی از آموزش برنامه نویسی تابعی Functional Programming در سی شارپ که یکی از بهترین بسته های آموزشی وبسایت پرووید می باشد استفاده کنید. اگر سیستم عامل سیستم شما در حال حاضر ویندوز می باشد احتمال اینکه دات نت فریم ورک بر روی آن نصب شده باشد بسیار زیاد است.

در این سری آموزشی از وبسایت پرووید قصد داریم در رابطه تکنیک هایی که می توایند به منظور افزایش سرعت برنامه های دات نت استفاده کنید صحبت کنیم. این سری تکنیک ها به منظور افزایش هر چه بیشتر سرعت در برنامه های دات نت می شوند. ضمناً توصیه می کنیم که از ده تکنیک افزایش سرعت برنامه های تحت وب نیز دیدن کنید.

تکنیک اول: به ایجاد استثناهای کمتر

ایجاد اسثتناها مشکلات زیادی را برای کارایی برنامه در دات نت ایجاد می کند. گاهی ممکن است تعداد استثناهایی که برنامه شما ایجاد می کند بیش از حد انتظار باشد. بنابراین، از ابزارهایی شبیه Perfmon برای تست کردن تعداد استثناهای ایجاد شده در برنامه کمک بگیرید. به علاوه می توانید توسط Performance Counter ها تعداد استثناها رو کنترل کنید.

دقت کنید که داشتن بلاک های متعدد Try/Catch مشکلی را به خودی خود برای شما ایجاد نمیکنند. مشکل از آنجا شروع می شود که استثنا مورد نظر ایجاد می شود. آنجاست که کارایی برنامه دات نت شما دچار مشکل می شود. بنابراین، تعداد زیادی بلاک های Try/Catch را با تعداد زیاد استثناها اشتباه نگیرید. به منظور فراگیری بهتر این مباحث می توانید به بسته ی جامع آموزش سی شارپ رجوع کنید.

به عنوان یک مثال ساده، به کد زیر دقت کنید. در کد زیر، تعدادی استثنا در یک حلقه ی تکرار For ایجاد می شوند. اجرا شدن این حلقه ی For باعث ایجاد هزاران استثنا می شود. برای پی بردن به بهبود کارایی، کد ایجاد شدن استثنا در حلقه را حذف کنید و خودتان سرعت اجرای برنامه را مقایسه کنید.

 
for (int i = 0; i > 10000; i++)
{
try
{
j = i;
throw new System.Exception();
}
catch { }
}
System.Console.Write(j);
return;
}
  • یکی از موضوع های مهم این است که استفاده ی معمولی از بعضی از توابع شبیه Redirect() خود باعث ایجاد استثنایی از نوع ThreadAbort می شود. این نوع از استثناها قابل اجتناب نیستند. بنابراین، نگران آنها نباشید.
  • برنامه نویسان ویژوال بیسیک دقت کنند که بطور پیش فرض عملیاتی شبیه overflow و تقسیم بر صفر برای نوع داده ای int کنترل می شود که این خود باعث کاهش کارایی می گردد. به منظور افزایش کارایی می توان این گزینه را غیرفعال کرد.
  • اگر از COM استفاده می کنید، دقت کنید که HRESULT ها باعث ایجاد استثنا می شوند. بنابراین، آنها را کنترل کنید.

پس به عنوان اولین تکنیک از سری آموزشی ده تکنیک افزایش سرعت اجرای برنامه در دات نت، تعداد استثناها را کنترل کنید و سعی کنید آنها را به حداقل برسانید.

تکنیک دوم: به فراخوانی های چندگانه

فراخوانی های چندگانه (Chunky Calls)، فراخوانی هایی هستند که چندین کار را به طور یک جا انجام می دهند. در مقابل، فراخوانی های یک گانه (Chatty Calls) آن فراخوانی هایی هستند که فقط یک کار را انجام میدهند. به منظور افزایش سرعت اجرای برنامه به خصوص در شرایطی که از متدهایی استفاده می کنید که در یک AppDomain دیگر هستند و یا متدهایی شبیه P/Invoke، Remote Call و غیره باید سعی کنید از فراخوانی های چندگانه استفاده کنید. این نوع فراخوانی ها سرباز زیادی دارند و با استفاده از روش فراخوانی چندگانه می توان این سربار را به حداقل رساند.

پس، سعی کنید تا حد امکان، کارهای متعددی را در یک فراخوانی به صورت یک جا انجام دهید و از فراخوانی های مکرر به خصوص در شرایطی که سربار زیادی متوجه برنامه می شود جلوگیری کنید. به منظور یادیگری کامل برنامه نویسی سی شارپ به آموزش سی شارپ دات نت در ویژوال استادیو رجوع کنید.

تکنیک سوم: به استفاده از Value Type ها

استفاده از Value Type ها به مراتب سرعت بیشتری از Reference Type ها دارد. به عبارت دیگر، هر گاه که ممکن است باید از struct ها به جای class استفاده کرد. این موضوع باعث می شود که زمان سربار عملیات boxing و unboxing از بین برود. در بسته ی آموزش برنامه نویسی شی گرا در سی شارپ بیشتر در این رابطه فرا می گیرید. به مثال زیر توجه کنید:

 
class Program
{
public struct foo
{
public foo(double arg) { this.y = arg; }
public double y;
}
public class bar
{
public bar(double arg) { this.y = arg; }
public double y;
}
private static void Main(string[] args)
{
System.Console.WriteLine("starting struct loop...");
for (int i = 0; i < 50000000; i++)
{
foo test = new foo(3.14);
}
System.Console.WriteLine("struct loop complete. starting object loop...");
for (int i = 0; i < 50000000; i++)
{
bar test2 = new bar(3.14);
}
System.Console.WriteLine("All done");
}
}

اگر مثال بالا را اجرا کنید خواهید دید که سرعت اجرای struct به مراتب بیشتر است. یک نکته ی بسیار مهم در کد بالا این است که اگر با value type ها شبیه object ها رفتار کنید، دچار عملیات boxing و unboxing می شوید که این خود سرعت اجرای برنامه را شدیداً کاهش می دهد. برای تست این موضوع در کد بالا، از آرایه ها استفاده کنید. در این صورت خواهید دید که سرعت اجرای هر دو روش تقریباً یک اندازه است.

دقت کنید که value type ها نسبت بهreference type ها به مراتب انعطاف پذیری کمتری دارند و استفاده ی نادرست از آنها سرعت اجرای برنامه را به شدت کاهش می دهد. برای مثال، اگر در کد بالا از hashtable و یا آرایه استفاده کنید، خواهید دید که سرعت اجرا به شدت کاهش می یابد. دلیل این موضوع ایجاد تنها یک عمل boxing و unboxing است.

پس به عنوان تکنیک سوم از سری تکنیک های افزایش سرعت اجرای برنامه در دات نت، سعی کنید از value type ها در شرایطی که به قابلیت های reference type ها نیازی ندارید استفاده کنید.

تکنیک چهارم: به استفاده از AddRange

به منظور اضافه کردن یک لیست از ایتم ها به یک کالکشن حتماً از AddRange استفاده کنید. متد Add به منظور اضافه کردن یک تک ایتم به یک کالکشن و متد AddRange به منظور اضافه کردن گروهی از ایتم ها به یک کالکشن می باشد. متد AddRange سربارهای اضافی نیز دارد اما در شرایطی که قصد اضافه کردن گروهی از ایتم ها به یک کالکشن را دارید به مراتب بهتر از یک حلقه ی تکرار و متد Add عمل می کند. همین جا از شما دعوت می کنیم که از آموزش رایگان برنامه نویسی با زبان سی شارپ دیدن کنید. این آموزش نیز می تواند به عنوان یک آموزش رایگان برای شما بسیار مفید باشد.

تقریباً تمامی کنترل ها و کالکشن ها از متد AddRange پشتیبانی می کنند. برای مثال:

  • StringCollection
  • TraceCollection
  • HttpWebRequest
  • UserControl
  • ColumnHeader

پس سعی کنید به عنوان یک تکنیک دیگر از سری آموزش ده تکنیک افزایش سرعت اجرای برنامه در دات نت، از AddRange برای اضافه کردن لیستی از ایتم ها به یک کالکشن استفاده کنید و از Add و یک حلقه ی تکرار به هیچ وجه استفاده نکنید.

تکنیک پنجم: به کوچک کردن Working Set

به منظور افزایش سرعت برنامه های دات نت می توان تعداد اسمبلی هایی که برنامه به آنها Reference داده است را کاهش داد. این امر باعث کاهش working set برنامه شده و سرعت اجرا را افزایش می دهد. اگر به منظور استفاده از یک تک متد در یک اسمبلی، کل آن اسمبلی را load می کنید، شک نکنید که در حال ضربه زدن به سرعت اجرای برنامه هستند. برای جلوگیری از این موضوع سعی کنید که کد مورد نیاز را با روش دیگری تولید کنید.

زیر نظر گرفتن working set برنامه کار تقریبا دشواری است. می توانید از تکنیک های زیر برای این کار استفاده کنید.

  • از ابزار exe برای کنترل working set برنامه استفاده کنید.
  • از ابزار Perfmon استفاده کنید. این ابزار، تعداد اسمبلی های لود شده، تعداد کلاسها و یا حتی تعداد متدها را به شما نشان می دهد. یکی از نکات جالب دیگر این ابزار این است که مدت زمانی که برنامه صرف لود کردن اسمبلی ها می کند را نیز به شما نشان می دهد.

به منظور یادیگری کامل برنامه نویسی سی شارپ به آموزش سی شارپ دات نت در ویژوال استادیو رجوع کنید. بنابراین، به عنوان تکنیک پنجم از سری آموزش ده تکنیک افزایش سرعت اجرا در برنامه های دات سعی کنید که از اسمبلی های غیرضروری در برنامه خود استفاده نکنید.

تکنیک ششم: به استفاده از StringBuilder برای کار با رشته ها

وقتی که یک رشته را تغییر می دهید، این امر باعث ایجاد یک رشته ی جدید میشود. اصطلاحاً، رشته های immutable هستند. این موضوع اغلب بسیار سریع اتفاق می افتد. اما، اگر به طور مکرر با رشته ها کار می کنید، تغییرات متعدد بر روی یک رشته باعث کاهش سرعت اجرای برنامه می شود. به عنوان یک راهکار مناسب، از کلاس StringBuilder استفاده کنید. از شما دعوت می کنیم که از آموزش رایگان کلاس SecureString در سی شارپ و آموزش رایگان ساختن یک Secure TextBox در سی شارپ نیز دیدن کنید.

کلاس StringBuilder در انجام عملیات معمول بر روی رشته ها از قبیل اضافه کردن (Append) عملکرد بسیار بالایی دارد. به دو تکه کد زیر دقت کنید. کد اول بدون استفاده از کلاس StringBuilder نوشته شده است و کد دوم از کلاس StringBuilder استفاده می کند.

 
public static void Main(string[] args)
{
string s = "monkeys!";
int dummy = 0;
System.Text.StringBuilder sb = new System.Text.StringBuilder(s);
for (int i = 0; i < 1000000; i++)
sb.Append(s);
s = sb.ToString();
//foreach (char c in s) dummy++;
for (int i = 0; i < 1000000; i++)
dummy++;
return;
}

استفاده از کلاس StringBuilder سرعت کار با رشته ها را در برنامه ی شما رو به شدت افزایش می دهد. با استفاده از ابزار Perfmon می توان مدت زمان دقیقی که با استفاده از StringBuilder ذخیره شده و به هدر نمی رود را به دست آورد. این آموزش رایگان نیز می تواند برای شما بسیار مفید باشد. مباحثی که در این آموزش رایگان منتشر شده است بسیار کلیدی و کاربردی می باشند. بنابراین، از شما دعوت می کنیم که حتماً این آموزش را نیز استفاده کنید.

نکته: دقت کنید که استفاده از کلاس StringBuilder نیز سربارهایی را برای حافظه و پردازنده دارد. به طور کلی، اگر قصد دارید ده عمل رشته ای یا بیشتر را انجام دهید، بهتر است از StringBuilder استفاده کنید.

به منظور یادیگری کامل برنامه نویسی سی شارپ به آموزش سی شارپ دات نت در ویژوال استادیو رجوع کنید. بنابراین، به عنوان تکنیک ششم از سری آموزش ده تکنیک افزایش سرعت اجرا در برنامه های دات سعی کنید که از کلاس StringBuilder برای کار کردن با رشته ها استفاده کنید.

تکنیک هفتم: به پیش کامپایل کردن Windows Form Application ها

یکی از موضوع های بسیار مهم در نظر گرفتن زمان ابتدای شروع به کار برنامه است. اگر برنامه ی شما در زمان شروع به کار خود، تعداد زیادی از متد ها را لود می کند و یا فراخوانی می کند، این موضوع باعث کاهش سرعت شدید اجرای برنامه می شود. این موضوع در برنامه های تحت ویندوز مشهود تر است، چرا که آنها از کتابخانه های زیادی در خود استفاده می کنند. اغلب اوقات، پیش کامپایل کردن (Precompile) کردن برنامه های تحت ویندوز باعث افزایش سرعت اجرا می شود.

شما می توانید به صورت خیلی ساده با استفاده از ngen.exe برنامه ی خود را پیش کامپایل کنید. از ابزار ngen.exe هم می توان در پروسه ی نصب برنامه و هم قبل از توزیع آن استفاده کرد. استفاده از ngen.exe قبل از نصب برنامه بهتر است چرا که این موضوع باعث می شود بر اساس پیکربندی ماشین مقصد، عملیات پیش کامپایل اتفاق بیفتد. به عبارت دیگر، پیش کامپایل کردن قبل از توزیع برنامه باعث می شود که بهبودهای انجام شده فقط مختص پیکربندی سیستم شما باشد.

برای اینکه افزایش سرعت بدست آمده توسط پیش کامپایل را نشان دهیم، به دو تست زیر توجه کنید. این دو تست زمان اجرای برنامه ی تحت ویندوزی به نام ShowFormComplex را نشان می دهد.

به دلیل استفاده ی زیاد برنامه های تحت ویندوز از متدها در زمان شروع به کار، استفاده از پیش کامپایل به شدت سرعت اجرای برنامه را افزایش می دهد. بنابراین، به عنوان تکنیک هفتم از سری آموزش ده تکنیک افزایش سرعت اجرا در برنامه های دات سعی کنید که برنامه های Windows Form Application خود را مورد پیش کامپایل قرار دهید.

تکنیک هشتم: به استفاده از DataReader به جای DataSet

استفاده از DataReader در مواقعی که فقط نیاز به خواندن داده ها دارید می تواند سرعت برنامه را افزایش دهد. DataReader می تواند در صورت تمایل کاربر داده ها را کش کند. یک DataReader به شما این امکان را می دهد که داده ها را بدون ذخیره سازی به صورت یک stream بخوانید که این موضوع سرعت خواندن داده ها از آن را به مراتب بیش از DataSet می کند.

در مقابل، از DataSet زمانی استفاده کنید که به عملیاتی بیش از خواندن داده ها نیاز دارید. DataSet نسبت به DataReader سربار بیشتری دارد. استفاده کردن از تکنولوژی Entity Framework نسبت به ADO.NET برتری هایی را دارد که می توانید برای یادگیری کار با این تکنولوژی در زمینه ی بانک های اطلاعاتی از آموزش 5 Entity Framework در سی شارپ استفاده کنید.

توجه کنید که اگر نیازی به کش کردن داده ها ندارید، استفاده از DataReader می تواند به شدت کارایی برنامه را افزایش دهد.

بنابراین، به عنوان تکنیک هشتم از سری آموزش ده تکنیک افزایش سرعت اجرا در برنامه های دات سعی کنید که در صورت عدم نیاز به DataSet از آن استفاده نکنید چرا که سربار بیشتری در برنامه ایجاد می کند. سعی کنید زمانی که نیاز به یک stream برای خواندن داده ها دارید از DataReader استفاده کنید.

تکنیک نهم: غیرفعال کردن گزینه های اضافی در Connection String

استفاده از حوضچه ی کانکشن ها می تواند به مراتب سرعت کار با بانک های اطلاعاتی در برنامه را افزایش دهد. دقت کنید که حوضچه ی کانکشن ها فقط زمانی ایجاد می شود که connection string تغییری نکند. به عبارت دیگر، اگر از یک connection string یکسان بارها استفاده کنید، به صورت خودکار این قابلیت شروع به کار کرده و سرعت کار را افزایش می دهد.

به علاوه، تنظیم نکردن موارد غیرضروری در تعریف connection string می تواند سرعت کار را بالا ببرد. برای مثال به connection string زیر نگاه کنید:

 
SqlConnection conn = new SqlConnection (“Server=mysrv01; Integrated Security=true; Enlist=false");

در connection string بالا، قابلیت Enlist با مقدار False تنظیم شده است که این موضوع به مراتب سرعت کار را بالا می برد. به عنوان مثالی دیگر، هنگامی که قصد پر کردن DataSet ی را با یک DataAdapter دارید، اگر نیازی به کلید اصلی جدول ندارید، آن را از دیتابیس نخوانید:

 
public DataSet SelectSqlSrvRows(DataSet dataset,string connection,string query){
SqlConnection conn = new SqlConnection(connection);
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand(query, conn);
adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;
adapter.Fill(dataset);
return dataset;
}

در کد بالا MissingSchemaAction با مقدار MissingSchemaAction.AddWithKey تنظیم شده است . این موضوع باعث می شود که اطلاعات کلید اصلی جدول نیز خوانده شود که در مواقعی که به آن نیازی نیست سرعت کار را بی جهت کاهش می دهد.

بنابراین، به عنوان تکنیک نهم از سری آموزش ده تکنیک افزایش سرعت اجرا در برنامه های دات سعی کنید در عملیات کار کردن با بانک اطلاعاتی، گزینه های غیر ضروری را غیرفعال کنید. این موضوع می تواند سرعت اجرا با بهبود ببخشد.

تکنیک دهم: مربوط به استفاده از عملایت IO بصورت ناهمزمان (Asynchronous)

اغلب اوقات برنامه های ما با داده ها کار می کنند. این عملیات می تواند شامل خواندن از یک فایل متنی، نوشتن بر روی یک stream و یا هر کار دیگری باشد. همزمان کردن کارهای IO با کارهای پردازشی که توسط CPU انجام میگیرد می تواند به طور قابل توجهی سرعت کار را افزایش دهد. دقت کنید که اگر این عمل به صورت درست و دقیق انجام نشود می تواند سرعت اجرای برنامه را به شدت کاهش دهد. ما در بسته ی جامع آموزش برنامه نویسی موازی، در رابطه با تکنیک های موازی سازی برنامه ها صحبت کرده ایم.

نوشتن کدهای عملیات IO به طور ناهمزمان با عملیات محاسباتی برنامه که توسط CPU انجام می شود، می تواند تا ده برابر برنامه را سریع تر کند. از نظر امنیت نیز نکاتی در این زمینه وجود دارد که باید به آنها دقت شود. به عنوان مثال، ارسال داده های stack متد فراخوان به فراخوانده شده یکی از موضوع هایی ست که از نظر امنیتی باید به آن توجه کرد.

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

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *