بهینهسازی قالببندی رشتهها در NET.: معرفی CompositeFormat
نویسنده: وحید نصیری
تاریخ: ۱۴۰۴/۰۸/۰۴ ۰۹:۳۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
for (int i = 0; i < 10000; i++)
{
string message = string.Format("Processing item {0} of {1}", i, 10000);
// استفاده یا لاگ کردن پیام
}"Processing item {0} of {1}" در هر چرخه از حلقه، بارها و بارها توسط متد string.Format پردازش میشود. این پردازش شامل تجزیه (parsing) رشته قالب، شناسایی جایگاهها (placeholders)، اعتبارسنجی ساختار و تولید رشته نهایی است. حالا تصور کنید این حلقه در یک برنامه با توان عملیاتی بالا (مثل وبسرور یا سیستم پردازش دستهای) اجرا شود. تجزیه مکرر یک رشته قالب یکسان، به معنای هدررفت منابع محاسباتی است. اینجاست که مشکل اصلی نمایان میشود: هزینه پردازش مکرر یک رشته قالب ثابت. این هزینه در سناریوهای واقعی مثل لاگ کردن با فرکانس بالا، پردازش درخواستهای وب یا سیستمهای بلادرنگ بهسرعت انباشته میشود و میتواند عملکرد برنامه را تحت تأثیر قرار دهد. آیا راهی برای حذف این پردازش اضافی وجود دارد؟$"Processing item {i} of {10000}". این روش خواناتر است و برای سناریوهای یکبارمصرف عالی است، اما در پشت صحنه همچنان پردازش مشابهی انجام میدهد و برای سناریوهای تکراری بهینه نیست.// تجزیه رشته قالب یکبار
CompositeFormat format = CompositeFormat.Parse("Processing item {0} of {1}");
for (int i = 0; i < 10000; i++)
{
// استفاده مجدد از قالب تجزیهشده
string message = string.Format(null, format, i, 10000);
// استفاده یا لاگ کردن پیام
}CompositeFormat.Parse تجزیه میشود و نتیجه در یک نمونه CompositeFormat ذخیره میشود. سپس در هر چرخه از حلقه، بهجای تجزیه دوباره، از این نمونه برای جایگزینی مقادیر استفاده میکنیم. نتیجه؟ حذف ۹,۹۹۹ پردازش اضافی در این مثال!CompositeFormat در واقع منطق تجزیه رشته قالب را از string.Format قرض گرفته، اما نتیجه را ذخیره میکند. وقتی CompositeFormat.Parse را فراخوانی میکنید، رشته قالب اسکن میشود، جایگاهها شناسایی میشوند و یک نمایش داخلی (شامل متن ثابت و جایگاهها) ساخته میشود. این نمایش تغییرناپذیر (immutable) و ایمن برای استفاده در چندنخی (thread-safe) است. در زمان قالببندی، متد string.Format با دریافت نمونه CompositeFormat، مستقیماً مقادیر را جایگزین میکند و نیازی به تجزیه مجدد ندارد.CompositeFormat میتواند زمان اجرا را ۱۵ تا ۳۰ درصد کاهش دهد، تخصیص حافظه (allocations) را کم کند و فشار بر جمعآوری زباله (Garbage Collection) را کاهش دهد. این بهبود در سناریوهایی مثل لاگ کردن با فرکانس بالا، پردازش درخواستهای وب یا سیستمهای تلهمتری بسیار ارزشمند است.CompositeFormat برای سناریوهایی مناسب است که یک رشته قالب بهصورت مکرر استفاده میشود، مثل:CompositeFormat بیشتر از صرفهجویی آن خواهد بود.static readonly ذخیره کنید:private static readonly CompositeFormat LogFormat =
CompositeFormat.Parse("User {0} logged in at {1:yyyy-MM-dd HH:mm:ss}");
for (int userId = 1; userId <= 1000; userId++)
{
string message = string.Format(null, LogFormat, userId, DateTime.Now);
Console.WriteLine(message);
}public static class MessageFormats
{
public static readonly CompositeFormat ErrorFormat =
CompositeFormat.Parse("Error: {0} occurred at {1}");
public static readonly CompositeFormat SuccessFormat =
CompositeFormat.Parse("Success: Operation {0} completed with result {1}");
}
// استفاده در برنامه
string errorMessage = string.Format(null, MessageFormats.ErrorFormat,
exception.Message, DateTime.UtcNow);CompositeFormat را بهصورت static readonly ذخیره کنید تا از ایجاد مکرر آنها جلوگیری شود.CompositeFormat را فقط در آنجا اعمال کنید.CompositeFormat را با StringBuilder ترکیب کنید تا تخصیص حافظه کاهش یابد.CompositeFormat در .NET 8 معرفی شد، اما در نسخههای بعدی بهبود یافت:Span و Memory برای سناریوهای بدون تخصیص.CompositeFormat را به شما میدهد، بلکه از بهبودهای کلی runtime نیز بهرهمند میشوید.CompositeFormat بخشی از تلاش گستردهتر .NET برای ارائه abstractions با هزینه صفر است. ابزارهایی مثل Span، Memory، ArrayPool و ValueTask همگی با هدف کاهش تخصیص و بهبود عملکرد طراحی شدهاند. این ابزارها به توسعهدهندگان اجازه میدهند بدون قربانی کردن خوانایی یا سهولت استفاده، کنترل کاملی بر عملکرد داشته باشند. CompositeFormat دقیقاً در این مسیر قرار دارد: یک تغییر کوچک با تأثیر بزرگ.CompositeFormat یک ابزار ساده اما قدرتمند در .NET 8 و بالاتر است که به شما امکان میدهد هزینه پردازش مکرر رشتههای قالب را حذف کنید. با تجزیه یکبار و استفاده چندباره، میتوانید عملکرد برنامه را در سناریوهای پرمصرف مثل لاگ کردن، پردازش درخواستها و سیستمهای بلادرنگ بهبود دهید.CompositeFormat مهاجرت کنید. نتیجه؟ کاهش مصرف CPU، تأخیر کمتر و توان عملیاتی بیشتر. این همان چیزی است که توسعهدهندگان حرفهای به دنبالش هستند: تغییر ساده، نتایج قابل اندازهگیری.