CodeBlanks Logo Icon CodeBlanks

Bellek ve Span

C# kursu · Uzman · Ders 44/47

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

  1. ReadOnlySpan bildirimini tamamla

    ReadOnlySpan<____> log
    Cevabı göster
    ReadOnlySpan<char> log
  2. 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.

  3. 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

Uzman bölümündeki tüm dersler