To pytanie nie jest tak proste, jak przedstawiają je inne plakaty (i tak mi się początkowo wydawało) - ponieważ nie jest do końca precyzyjne, jak powinno.
Istnieje różnica między „spacją” a „białą spacją”. Jeśli masz na myśli tylko spacje, powinieneś użyć wyrażenia regularnego od " {2,}"
. Jeśli masz na myśli jakąkolwiek białą spację, to inna sprawa. Powinien wszystko spacje powinny zostać zamienione na spacje? Co powinno się stać z przestrzenią na początku i na końcu?
W przypadku testu porównawczego poniżej założyłem, że obchodzą Cię tylko spacje i nie chcesz nic robić z pojedynczymi spacjami, nawet na początku i na końcu.
Zauważ, że poprawność jest prawie zawsze ważniejsza niż wydajność. Fakt, że rozwiązanie Split / Join usuwa wszelkie początkowe / końcowe spacje (nawet tylko pojedyncze spacje) jest niepoprawne, jeśli chodzi o określone wymagania (które oczywiście mogą być niekompletne).
Benchmark wykorzystuje MiniBench .
using System;
using System.Text.RegularExpressions;
using MiniBench;
internal class Program
{
public static void Main(string[] args)
{
int size = int.Parse(args[0]);
int gapBetweenExtraSpaces = int.Parse(args[1]);
char[] chars = new char[size];
for (int i=0; i < size/2; i += 2)
{
// Make sure there actually *is* something to do
chars[i*2] = (i % gapBetweenExtraSpaces == 1) ? ' ' : 'x';
chars[i*2 + 1] = ' ';
}
// Just to make sure we don't have a \0 at the end
// for odd sizes
chars[chars.Length-1] = 'y';
string bigString = new string(chars);
// Assume that one form works :)
string normalized = NormalizeWithSplitAndJoin(bigString);
var suite = new TestSuite<string, string>("Normalize")
.Plus(NormalizeWithSplitAndJoin)
.Plus(NormalizeWithRegex)
.RunTests(bigString, normalized);
suite.Display(ResultColumns.All, suite.FindBest());
}
private static readonly Regex MultipleSpaces =
new Regex(@" {2,}", RegexOptions.Compiled);
static string NormalizeWithRegex(string input)
{
return MultipleSpaces.Replace(input, " ");
}
// Guessing as the post doesn't specify what to use
private static readonly char[] Whitespace =
new char[] { ' ' };
static string NormalizeWithSplitAndJoin(string input)
{
string[] split = input.Split
(Whitespace, StringSplitOptions.RemoveEmptyEntries);
return string.Join(" ", split);
}
}
Kilka testów:
c:\Users\Jon\Test>test 1000 50
============ Normalize ============
NormalizeWithSplitAndJoin 1159091 0:30.258 22.93
NormalizeWithRegex 26378882 0:30.025 1.00
c:\Users\Jon\Test>test 1000 5
============ Normalize ============
NormalizeWithSplitAndJoin 947540 0:30.013 1.07
NormalizeWithRegex 1003862 0:29.610 1.00
c:\Users\Jon\Test>test 1000 1001
============ Normalize ============
NormalizeWithSplitAndJoin 1156299 0:29.898 21.99
NormalizeWithRegex 23243802 0:27.335 1.00
Tutaj pierwsza liczba to liczba iteracji, druga to czas potrzebny, a trzecia to wynik skalowany, przy czym 1.0 to najlepszy.
To pokazuje, że przynajmniej w niektórych przypadkach (w tym w tym jednym) wyrażenie regularne może przewyższać rozwiązanie Split / Join, czasami z bardzo dużym marginesem.
Jednakże, jeśli zmieni się na „wszystko” wymóg spacji, a następnie Split / Dołącz nie wydaje się, aby wygrać. Jak to często bywa, diabeł tkwi w szczegółach ...