Method Substring mengambil potongan teks dengan menyalin karakter-karakternya ke objek string baru. Pada data kecil, biaya salinan ini tidak terasa; pada pengolahan teks bervolume besar, salinan menumpuk dan membebani garbage collector. Tipe ReadOnlySpan<char> menawarkan jalan lain: span memandang rentang karakter yang sudah ada tanpa menyalin apa pun. Bab ini memperkenalkan pemakaiannya pada string di level pengantar.
ReadOnlySpan<char> pada String #
Method AsSpan mengubah string menjadi ReadOnlySpan<char>. Span mendukung properti Length, pengindeksan, dan pemotongan lewat AsSpan(start, length) — semuanya tanpa alokasi baru:
string pesanan = "Kopi Susu Gula Aren";
ReadOnlySpan<char> semua = pesanan.AsSpan();
Console.WriteLine(semua.Length);
Console.WriteLine(semua[5]);
Console.WriteLine(pesanan.AsSpan(0, 4).ToString());
Console.WriteLine(pesanan.AsSpan(10).ToString());
Console.WriteLine(pesanan.AsSpan(5, 4).SequenceEqual("Susu".AsSpan()));Output yang Dihasilkan:
19
S
Kopi
Gula Aren
TrueMari kita telaah baris demi baris:
- Baris 3 (
pesanan.AsSpan()): Span memandang seluruh 19 karakter string; tidak ada salinan yang dibuat, hanya alamat dan panjang yang dicatat. - Baris 5 (
semua[5]): Pengindeksan membaca karakter pada posisi5langsung dari string asal, yaituS. - Baris 7-8 (
AsSpan(0, 4)danAsSpan(10)): Pemotongan hanya menggeser jendela pandang;ToString()baru membuat string saat hasilnya benar-benar dicetak. - Baris 9 (
SequenceEqual): Perbandingan karakter berjalan di atas span tanpa menyalin; potongan posisi5sepanjang 4 karakter sama dengan"Susu", sehingga hasilnyaTrue.
Buffer di Stack dengan stackalloc #
Selain membaca data yang sudah ada, span juga bisa menampung buffer sementara lewat stackalloc. Alokasinya berada di stack dan dibersihkan otomatis saat method selesai, tanpa campur tangan garbage collector:
Span<char> inisial = stackalloc char[3];
inisial[0] = 'K';
inisial[1] = 'S';
inisial[2] = 'G';
Console.WriteLine(new string(inisial));Output yang Dihasilkan:
KSGstackalloc char[3] menyediakan tiga sel karakter di stack, dan setiap sel diisi lewat indeks. Konversi new string(inisial) hanya dilakukan sekali di akhir, saat teks benar-benar dibutuhkan sebagai string.
Memory<T> untuk Skenario Async #
Span<T> hidup di stack sehingga tidak boleh disimpan di field class maupun dipakai di dalam method async. Tipe Memory<T> menjadi jembatannya: semantiknya mirip span, tetapi boleh disimpan dan dilewatkan ke operasi asinkron:
ReadOnlyMemory<char> memori = pesanan.AsMemory(10, 4);
Console.WriteLine(memori.Span.ToString());Output yang Dihasilkan:
GulaAsMemory(10, 4) menandai rentang empat karakter mulai indeks 10. Properti Span pada Memory<char> mengembalikan span yang bisa dibaca kapan pun rentangnya dibutuhkan, dan pencetakan menampilkan Gula.