Dimulai dengan .NET Core 2.1 ada cara baru untuk membalikkan string menggunakan string.Create
metode ini.
Perhatikan bahwa solusi ini tidak menangani Unicode yang menggabungkan karakter dll dengan benar, karena "Les Mise \ u0301rables" akan dikonversi menjadi "selbarésiM seL". The jawaban yang lain untuk solusi yang lebih baik.
public static string Reverse(string input)
{
return string.Create<string>(input.Length, input, (chars, state) =>
{
state.AsSpan().CopyTo(chars);
chars.Reverse();
});
}
Ini pada dasarnya menyalin karakter input
ke string baru dan membalikkan string baru di tempat.
Kenapa string.Create
bermanfaat?
Ketika kami membuat string dari array yang ada, array internal baru dialokasikan dan nilai-nilai disalin. Kalau tidak, akan mungkin untuk memutasikan string setelah pembuatannya (dalam lingkungan yang aman). Yaitu, dalam cuplikan berikut ini, kami harus mengalokasikan array dengan panjang 10 dua kali, satu sebagai buffer dan satu sebagai array internal string.
var chars = new char[10];
// set array values
var str = new string(chars);
string.Create
dasarnya memungkinkan kita untuk memanipulasi array internal selama waktu pembuatan string. Ini, kita tidak perlu buffer lagi dan karena itu dapat menghindari mengalokasikan satu array char.
Steve Gordon telah menulisnya secara lebih rinci di sini . Ada juga artikel tentang MSDN .
Cara menggunakan string.Create
?
public static string Create<TState>(int length, TState state, SpanAction<char, TState> action);
Metode ini mengambil tiga parameter:
- Panjang string yang akan dibuat,
- data yang ingin Anda gunakan untuk secara dinamis membuat string baru,
- dan delegasi yang membuat string terakhir dari data, di mana parameter pertama menunjuk ke
char
array internal dari string baru dan yang kedua adalah data (status) yang Anda berikan string.Create
.
Di dalam delegasi kita dapat menentukan bagaimana string baru dibuat dari data. Dalam kasus kami, kami hanya menyalin karakter dari string input ke yang Span
digunakan oleh string baru. Kemudian kita membalikkannyaSpan
dan karenanya seluruh string dibalik.
Tolak ukur
Untuk membandingkan cara saya yang diusulkan untuk membalik string dengan jawaban yang diterima, saya telah menulis dua tolok ukur menggunakan BenchmarkDotNet.
public class StringExtensions
{
public static string ReverseWithArray(string input)
{
var charArray = input.ToCharArray();
Array.Reverse(charArray);
return new string(charArray);
}
public static string ReverseWithStringCreate(string input)
{
return string.Create(input.Length, input, (chars, state) =>
{
state.AsSpan().CopyTo(chars);
chars.Reverse();
});
}
}
[MemoryDiagnoser]
public class StringReverseBenchmarks
{
private string input;
[Params(10, 100, 1000)]
public int InputLength { get; set; }
[GlobalSetup]
public void SetInput()
{
// Creates a random string of the given length
this.input = RandomStringGenerator.GetString(InputLength);
}
[Benchmark(Baseline = true)]
public string WithReverseArray() => StringExtensions.ReverseWithArray(input);
[Benchmark]
public string WithStringCreate() => StringExtensions.ReverseWithStringCreate(input);
}
Inilah hasil di mesin saya:
| Method | InputLength | Mean | Error | StdDev | Gen 0 | Allocated |
| ---------------- | ----------- | -----------: | ---------: | --------: | -----: | --------: |
| WithReverseArray | 10 | 45.464 ns | 0.4836 ns | 0.4524 ns | 0.0610 | 96 B |
| WithStringCreate | 10 | 39.749 ns | 0.3206 ns | 0.2842 ns | 0.0305 | 48 B |
| | | | | | | |
| WithReverseArray | 100 | 175.162 ns | 2.8766 ns | 2.2458 ns | 0.2897 | 456 B |
| WithStringCreate | 100 | 125.284 ns | 2.4657 ns | 2.0590 ns | 0.1473 | 232 B |
| | | | | | | |
| WithReverseArray | 1000 | 1,523.544 ns | 9.8808 ns | 8.7591 ns | 2.5768 | 4056 B |
| WithStringCreate | 1000 | 1,078.957 ns | 10.2948 ns | 9.6298 ns | 1.2894 | 2032 B |
Seperti yang Anda lihat, dengan ReverseWithStringCreate
kami mengalokasikan hanya setengah dari memori yang digunakan oleh ReverseWithArray
metode ini.