Ab .NET Core 2.1 gibt es eine neue Möglichkeit, eine Zeichenfolge mithilfe der string.Create
Methode umzukehren .
Beachten Sie, dass diese Lösung Unicode-Kombinationszeichen usw. nicht korrekt verarbeitet, da "Les Mise \ u0301rables" in "selbarésiM seL" konvertiert wird. Die anderen Antworten für eine bessere Lösung.
public static string Reverse(string input)
{
return string.Create<string>(input.Length, input, (chars, state) =>
{
state.AsSpan().CopyTo(chars);
chars.Reverse();
});
}
Dies kopiert im Wesentlichen die Zeichen von input
in eine neue Zeichenfolge und kehrt die neue Zeichenfolge an Ort und Stelle um.
Warum ist string.Create
nützlich?
Wenn wir eine Zeichenfolge aus einem vorhandenen Array erstellen, wird ein neues internes Array zugewiesen und die Werte werden kopiert. Andernfalls wäre es möglich, eine Zeichenfolge nach ihrer Erstellung zu mutieren (in einer sicheren Umgebung). Das heißt, im folgenden Snippet müssen wir ein Array mit der Länge 10 zweimal zuweisen, eines als Puffer und eines als internes Array der Zeichenfolge.
var chars = new char[10];
// set array values
var str = new string(chars);
string.Create
Im Wesentlichen können wir das interne Array während der Erstellungszeit des Strings bearbeiten. Dies bedeutet, dass wir keinen Puffer mehr benötigen und daher die Zuweisung dieses einen Zeichenarrays vermeiden können.
Steve Gordon hat hier ausführlicher darüber geschrieben . Es gibt auch einen Artikel über MSDN .
Wie benutzt man string.Create
?
public static string Create<TState>(int length, TState state, SpanAction<char, TState> action);
Die Methode akzeptiert drei Parameter:
- Die Länge der zu erstellenden Zeichenfolge,
- die Daten, die Sie zum dynamischen Erstellen der neuen Zeichenfolge verwenden möchten,
- und ein Delegat, der die endgültige Zeichenfolge aus den Daten erstellt, wobei der erste Parameter auf das interne
char
Array der neuen Zeichenfolge verweist und der zweite die Daten (Status) ist, an die Sie übergeben haben string.Create
.
Innerhalb des Delegaten können wir angeben, wie die neue Zeichenfolge aus den Daten erstellt wird. In unserem Fall kopieren wir einfach die Zeichen der Eingabezeichenfolge in die Span
von der neuen Zeichenfolge verwendete. Dann kehren wir das um Span
und daher wird die gesamte Zeichenfolge umgekehrt.
Benchmarks
Um meine vorgeschlagene Methode zum Umkehren einer Zeichenfolge mit der akzeptierten Antwort zu vergleichen, habe ich zwei Benchmarks mit BenchmarkDotNet geschrieben.
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);
}
Hier sind die Ergebnisse auf meiner Maschine:
| 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 |
Wie Sie sehen können, ReverseWithStringCreate
weisen wir nur die Hälfte des von der ReverseWithArray
Methode verwendeten Speichers zu .