۲۹ شهریور ۱۴۰۳

Techboy

اخبار و اطلاعات روز تکنولوژی

نحوه کار با String.Create در سی شارپ

از مزایای String.Create برای ایجاد رشته‌هایی بدون سربار تخصیص و بهبود عملکرد برنامه‌های NET 6 خود استفاده کنید.

از مزایای String.Create برای ایجاد رشته‌هایی بدون سربار تخصیص و بهبود عملکرد برنامه‌های NET 6 خود استفاده کنید.

مدیریت رشته یکی از حیاتی ترین بخش های عملکرد در هر برنامه ای است. از آنجایی که رشته ها تغییر ناپذیر هستند، می توانید به راحتی بسیاری از اشیاء رشته ها را خیلی سریع جمع آوری کنید، در نتیجه تخصیص منابع حافظه ایجاد می شود که بر عملکرد برنامه تأثیر منفی می گذارد.

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

در ادامه بحث ما در مورد کارکردن با رشته ها، در این مقاله به نحوه استفاده از روش String.Create برای ایجاد رشته ها بدون سربار منبع خواهیم پرداخت. در حالی که فشرده‌سازی رشته یک تکنیک عالی برای کاهش مصرف منابع به طور کلی است، String.Create تکنیک دیگری است که می‌توانید از آن برای مدیریت کارآمد رشته‌ها استفاده کنید — اما فقط در شرایط خاصی که در مورد آن بحث خواهیم کرد.

برای کار با نمونه کدهای ارائه شده در این مقاله، باید Visual Studio 2022 را در سیستم خود نصب کنید. اگر قبلاً نسخه‌ای ندارید، می‌توانید Visual Studio 2022 را از اینجا بارگیری کنید.

یک پروژه برنامه کاربردی کنسول در Visual Studio 2022 ایجاد کنید

ابتدا، اجازه دهید یک پروژه برنامه کاربردی کنسول NET Core در ویژوال استودیو ایجاد کنیم. با فرض اینکه Visual Studio 2022 در سیستم شما نصب شده است، مراحل ذکر شده در زیر را برای ایجاد یک پروژه برنامه کاربردی کنسول NET Core جدید دنبال کنید.

  1. Visual Studio IDE را راه اندازی کنید.
  2. روی “ایجاد پروژه جدید” کلیک کنید.
  3. در پنجره “ایجاد یک پروژه جدید”، “Console App” را از لیست الگوهای نمایش داده شده انتخاب کنید.
  4. بعدی را کلیک کنید.
  5. در پنجره “پیکربندی پروژه جدید خود” که در ادامه نشان داده شده است، نام و مکان پروژه جدید را مشخص کنید.
  6. در پنجره “اطلاعات اضافی”، .NET 6.0 را به عنوان زمان اجرا انتخاب کنید و روی Next کلیک کنید
  7. روی ایجاد کلیک کنید.
JetBrains اصلاحات امنیتی را برای سیستم TeamCity CI/CD منتشر می کند

ما از این پروژه برنامه کاربردی کنسول NET 6 برای کار با رشته‌ها در بخش‌های زیر استفاده خواهیم کرد.

Span و Memory

Span و Memory ساختارهایی هستند که در نسخه های جدیدتر دات نت اضافه شده اند و به به حداقل رساندن تخصیص ها کمک می کنند. آنها به عنوان یک نما روی یک رشته، آرایه یا هر بلوک پیوسته حافظه کار می کنند. آنها همتاهای فقط خواندنی دارند. همتای فقط خواندنی ساختار Span ReadOnlySpan است و همتای فقط خواندنی Memory ReadOnlyMemory است.

متد String.Create در سی شارپ

متد String.Create در نسخه های اخیر C# اضافه شده است. در اینجا نحوه اعلان متد Create از کلاس String آمده است:

public static string Create<TState> (int length, TState state, System.Buffers.SpanAction<char,TState> action);

روش String.Create به موارد زیر نیاز دارد:

  1. طول رشته برای ایجاد
  2. داده ها (یعنی وضعیت)
  3. یک تابع لامبدا که می تواند حالت را به یک رشته تبدیل کند

متد String.Create یک تکه از حافظه را به پشته اختصاص می دهد تا دنباله ای از کاراکترها را ذخیره کند. اولین پارامتر این روش طول رشته نهایی است. پارامتر دوم حالتی است که برای ساخت شی رشته لازم است. سومین و آخرین پارامتر یک نماینده است که باید روی داده ها در پشته اختصاص داده شده کار کند و شی رشته نهایی را تولید کند.

هنگامی که متد String.Create را فرا می‌خوانید، رشته جدیدی ایجاد می‌کند که اندازه‌ای از پیش تعریف شده دارد که با مقدار آرگومان طول شما تعیین می‌شود. توجه داشته باشید که این تنها تخصیص پشته ای است که هنگام استفاده از متد String.Create رخ می دهد. از آنجایی که متد Create عضوی از کلاس String است، می تواند به نمونه Span که نشان دهنده داده های کاراکتر داخلی نمونه رشته جدید است دسترسی داشته باشد.

Span خود یک اشاره گر است که در پشته قرار دارد اما می تواند روی حافظه پشته کار کند. اکشن لامبدا سنگین کردن سیم را انجام می دهد که در نهایت به شما بازگردانده می شود. به عبارت دیگر، هنگامی که اجرای تابع لامبدا کامل شد، متد String.Create یک مرجع به نمونه رشته جدیدی که ایجاد کرده است برمی گرداند.

زمان استفاده از روش String.Create

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

با استفاده از روش String.Create

در اینجا یک مثال ساده از استفاده از روش String.Create آورده شده است:

char[] buffer = { 'a', 'e', 'i', 'o', 'u' }; 
string result = string.Create(buffer.Length, buffer, (c, b) => {
    for (int i = 0; i < c.Length; i++) c[i] = b[i];
});

در زیر مثال دیگری وجود دارد که نشان می دهد چگونه می توانید از String.Create برای تولید شناسه های همبستگی استفاده کنید. کد زیر را در فایل Program.cs پروژه برنامه کاربردی کنسولی که قبلا ایجاد کردیم وارد کنید.

private static readonly char[] charactersToEncode = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".ToCharArray();
private static string GetCorrelationId(long id)
    {
        return string.Create(10, id, (buffer, value) =>
        {
            char[] characters = charactersToEncode;
            buffer[9] = characters[(value >> 5) & 31];
            buffer[8] = characters[(value >> 10) & 31];
            buffer[7] = characters[(value >> 15) & 31];
            buffer[6] = characters[(value >> 20) & 31];
            buffer[5] = characters[(value >> 25) & 31];
            buffer[4] = characters[(value >> 30) & 31];
            buffer[3] = characters[(value >> 35) & 31];
            buffer[2] = characters[(value >> 40) & 31];
            buffer[1] = characters[(value >> 45) & 31];
            buffer[0] = characters[(value >> 50) & 31];
        });
    }

برای دریافت شناسه همبستگی جدید، می‌توانید روش GetCorrelationId را از روش Main مانند شکل زیر فراخوانی کنید:

static async Task Main(string[] args)
    {
        Console.WriteLine(GetCorrelationId(DateTime.UtcNow.Ticks));
        Console.ReadKey();
    }

String.Create محدودیت ها و بهترین شیوه ها

هنگام استفاده از String.Create، اول از همه باید محدودیت های آن را در نظر داشته باشید. شما باید اندازه رشته ای را که می خواهید ایجاد کنید از قبل بدانید، که مستلزم دانستن طول اشیاء حالتی است که رشته نهایی از آنها تشکیل می شود.

هنگام کار با متد String.Create نیز باید دو روش برتر را رعایت کنید. اول، عاقلانه است که عملکرد برنامه خود را محک بزنید تا مطمئن شوید که استفاده از String.Create در واقع نتایج بهتری به همراه دارد. دوم، اگر از چندین شی برای حالت استفاده می‌کنید، حتماً از ValueTuples استفاده کنید.

در نهایت، توجه داشته باشید که String.Create ممکن است در سناریوهای خاصی انتخاب خوبی نباشد. وقتی خوانایی یا فرهنگ برای برنامه شما یا تیم توسعه شما مهم است، نباید از String.Create استفاده کنید.

بنابراین، اینکه آیا شما باید از String.Create استفاده کنید یا نه، به معاوضه بین جنبه‌های منفی و مزایای عملکرد آن بستگی دارد. توصیه من این است که کد خود را محک بزنید، نتایج را ببینید و سپس تصمیم بگیرید. در پست‌های بعدی اینجا بیشتر در مورد نوشتن کد عملکرد بالا خواهم نوشت.