欠けているように見える1つのオプションがあれば、ほぼ完全にカバーされます。2文字だけを削除する場合は、Replace.Replaceの使用が最も速く、配列操作と文字列ビルダーがそれに続きます。
Linq Whereとstring.Joinを使用すると、それほど重要ではありませんが、すべてが少し遅くなります。
正規表現(少なくとも.NET 4.5では)が期待したほど遅くないことに驚かれることでしょう。Linqを使用するよりもさらに高速です。コンパイルされた式またはデリゲートを使用する場合は、Linq式をもう少し高速化できる可能性があります。
文字列のより大きな部分、または2文字よりも多くの文字を置き換える必要がある場合、統計が変更される可能性があります。
static void Main(string[] args)
{
string str = "123456#23876587234687237*723547623547523745273#";
Console.WriteLine("Join+Where");
Test(s => String.Join("",s.Where(char.IsDigit)), str);
Console.WriteLine("ArrayOperation");
Test(s => new string(Array.FindAll(s.ToCharArray(), char.IsDigit)), str);
Console.WriteLine("Join+Select");
Test(s => string.Join("", s.Select(r=> char.IsDigit(r) ? r.ToString():"")), str);
Console.WriteLine("ReplaceReplace");
Test(s => s.Replace("*", "").Replace("#", ""), str);
Console.WriteLine("Regex");
Test(s => Regex.Replace(s, "[#*]", ""), str);
Console.WriteLine("Regex");
Regex rx = new Regex("[#*]", RegexOptions.Compiled);
rx.Match(""); // Precompile for better results
Test(s => rx.Replace(s, ""), str);
Console.WriteLine("StringBuilder");
Test(s => new StringBuilder(s).Replace("*", "").Replace("#", "").ToString(), str);
Console.ReadLine();
}
public static void Test(Func<string,string> proposedSolution, string input)
{
GC.Collect();
GC.WaitForPendingFinalizers();
Thread.Sleep(5000);
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 1000; i++)
{
string val = proposedSolution(input);
Debug.Write(val);
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}
「123456#23876587234687237 * 723547623547523745273#」の出力は次のとおりです(正規表現を適切に使用すると、人々が信じるほど遅くないことに気付くでしょう。
Join+Where
88
ArrayOperation
25
Join+Select
45
ReplaceReplace
18
Regex
39
Regex+Compiled
41
StringBuilder
19
これは、数字以外のすべてを置き換える必要がある場合に、より興味深いものになる可能性があります。または、より具体的には「#」と「*」。しかし、最終的には、簡単なテストを作成してから、最も理解しやすく実行しやすい方法を選択することがおそらく最善の解決策です。
注意すべき点の1つ:提供されているすべてのソリューションがまったく同じことを行うわけではありません。数字だけを保持するものもあれば、指定された入力から2文字を削除するものもあります。サンプルの場合、両方のオプションが有効であるように見えますが、違いを理解することが重要です。
LINQを使用して#と*だけを削除するのと同じオプション:
char[] Removechars = new[] { '#', '*' };
Console.WriteLine("Join+Where");
Test(s => String.Join("", s.Where(c => !Removechars.Contains(c))), str);
Console.WriteLine("ArrayOperation");
Test(s => new string(Array.FindAll(s.ToCharArray(), c => !Removechars.Contains(c))), str);
Console.WriteLine("Except");
Test(s => new string(s.ToCharArray().Except(Removechars).ToArray()), str);
Console.WriteLine("Join+Select");
Test(s => string.Join("", s.Select(c => !Removechars.Contains(c) ? c.ToString():"")), str);
これらのオプションはすべて、IsDigitまたは!IsDigitを使用するよりも低速です。