C#
Bellek ve Span
Span<T> ve unsafe kodla yüksek performanslı işlemler yazarsın.
Bellek ve Span
Span<T>, bir bellek bölgesine kopyasız bir pencere açar. ReadOnlySpan<char> ile bir string'in alt parçasını Split veya Substring olmadan işleyebilirsin; bu, tahsisat (allocation) yapmaz.
Bu derste ParseWithSpan metodunu ekleyeceğiz: log satırındaki seviye adını, ilk :'a kadar olan kısmı IndexOf ve Slice ile çıkarır. Ayrıca unsafe bir metotla işaretçi kullanımını gösterelim.
unsafe ile işaretçi
unsafe bloğu, işaretçiler (pointers) ile düşük seviye bellek erişimi sağlar. int* pa = &a; ile bir yerel değişkenin adresini alır, *pa ile değerini okursun. Bu, yüksek performans gerektiren sayısal işlemlerde faydalıdır.
Bu derste UnsafeSum metodu iki int'i işaretçi yoluyla toplayacak. Gerçek projelerde unsafe dikkatli kullanılır; çünkü bellek güvenliği garantisi kalkar.
Uygulama ParseWithSpan ve UnsafeSum ekle
LogProcessor'a iki metot ekle. public static string ParseWithSpan(ReadOnlySpan<char> log): int colon = log.IndexOf(':'); ile ':''ı bul, colon < 0 ise boş döndür, değilse log.Slice(0, colon).ToString() döndür. public static unsafe int UnsafeSum(int a, int b): int* pa = &a; int* pb = &b; return *pa + *pb;. Main'de Console.WriteLine(LogProcessor.ParseWithSpan("ERROR: disk".AsSpan())) ve Console.WriteLine(LogProcessor.UnsafeSum(3, 4)) çağır.
Örnek çözümü göster
disk".AsSpan())); ve Console.WriteLine(LogProcessor.UnsafeSum(3, 4));
Örnek çözüm:
using System;
static class LogProcessor
{
public static int ParseLevel(string level)
{
return level switch
{
"INFO" => 0,
"WARN" => 1,
"ERROR" => 2,
_ => -1
};
}
public static int CountByLevel(string[] logs, int targetLevel)
{
int count = 0;
foreach (var log in logs)
{
if (ParseLevel(log.Split(':')[0]) == targetLevel)
{
count++;
}
}
return count;
}
public static string ParseWithSpan(ReadOnlySpan<char> log)
{
int colon = log.IndexOf(':');
if (colon < 0) return "";
return log.Slice(0, colon).ToString();
}
public static unsafe int UnsafeSum(int a, int b)
{
int* pa = &a;
int* pb = &b;
return *pa + *pb;
}
}
class Program
{
static void Main()
{
Console.WriteLine("LogProcessor iskeleti hazır");
var logs = new[] { "INFO: a", "WARN: b", "INFO: c", "ERROR: d" };
Console.WriteLine(LogProcessor.CountByLevel(logs, 0));
Console.WriteLine(LogProcessor.ParseWithSpan("ERROR: disk".AsSpan()));
Console.WriteLine(LogProcessor.UnsafeSum(3, 4));
}
}
Kendini test et
-
ReadOnlySpan bildirimini tamamla
ReadOnlySpan<____> log
Cevabı göster
ReadOnlySpan<char> log
-
C#'ta işaretçi tanımlamak için hangi sembol kullanılır?
- & (adres)
- * (işaretçi)
- -> (üye erişim)
- sizeof (boyut)
Cevabı göster
* (işaretçi) — Doğru. * işaretçi tanımlar.
-
Span ve unsafe metotlarını eşleştir
- ReadOnlySpan<char>
- Kopyasız karakter görünümü
- IndexOf(':')
- İlk iki noktayı bul
- Slice(0, n)
- İlk n karakteri al
Sıradaki ders: Channels ve concurrent