データベーステーブルの文字列内で「、」で区切られた複数の電子メールアドレスを取得しようとしていますが、空白も返されるため、空白をすばやく削除したいです。
次のコードは空白を削除しますが、30000などの文字列で多数の電子メールアドレスを取得し、それらの間の空白を削除しようとすると、遅くなります。これらのスペースを削除するには、4〜5分以上かかります。
Regex Spaces =
new Regex(@"\s+", RegexOptions.Compiled);
txtEmailID.Text = MultipleSpaces.Replace(emailaddress),"");
多数の電子メールアドレスであっても、1秒以内に空白を削除する方法を教えてください。
次のように、StringBuilder
を使用してカスタム拡張メソッドを作成します。
public static string ExceptChars(this string str, IEnumerable<char> toExclude)
{
StringBuilder sb = new StringBuilder(str.Length);
for (int i = 0; i < str.Length; i++)
{
char c = str[i];
if (!toExclude.Contains(c))
sb.Append(c);
}
return sb.ToString();
}
使用法:
var str = s.ExceptChars(new[] { ' ', '\t', '\n', '\r' });
またはさらに高速にするために:
var str = s.ExceptChars(new HashSet<char>(new[] { ' ', '\t', '\n', '\r' }));
ハッシュセットバージョンでは、1100万文字の文字列にかかる時間は700ミリ秒未満です(デバッグモードです)
編集:
以前のコードは汎用であり、任意の文字を除外できますが、可能な限り高速で空白だけを削除する場合は次のように使用できます。
public static string ExceptBlanks(this string str)
{
StringBuilder sb = new StringBuilder(str.Length);
for (int i = 0; i < str.Length; i++)
{
char c = str[i];
switch (c)
{
case '\r':
case '\n':
case '\t':
case ' ':
continue;
default:
sb.Append(c);
break;
}
}
return sb.ToString();
}
編集2:
コメントで正しく指摘されているように、空白を削除する正しい方法はallchar.IsWhiteSpace
方法 :
public static string ExceptBlanks(this string str)
{
StringBuilder sb = new StringBuilder(str.Length);
for (int i = 0; i < str.Length; i++)
{
char c = str[i];
if(!char.IsWhiteSpace(c))
sb.Append(c);
}
return sb.ToString();
}
Linqを使用すると、簡単に実行できます。
emailaddress = new String(emailaddress
.Where(x=>x!=' ' && x!='\r' && x!='\n')
.ToArray());
私はそれを文字列ビルダーのアプローチと比較しませんでしたが、文字列ベースのアプローチよりもはるかに高速です。文字列のコピーをあまり作成しないため(文字列は不変であり、それを直接使用すると劇的にメモリと速度の問題が発生します)、非常に大きなメモリを使用せず、速度を遅くしません(1つの余分なパスを除きます)最初は文字列)。
emailaddress.Replace(" ", string.empty);
String.Trim()
を試してください。文字列の最初から最後まですべてのスペースをトリミングします
または、リンクされたトピックからこのメソッドを試すことができます: [link]
public static unsafe string StripTabsAndNewlines(string s)
{
int len = s.Length;
char* newChars = stackalloc char[len];
char* currentChar = newChars;
for (int i = 0; i < len; ++i)
{
char c = s[i];
switch (c)
{
case '\r':
case '\n':
case '\t':
continue;
default:
*currentChar++ = c;
break;
}
}
return new string(newChars, 0, (int)(currentChar - newChars));
}
多くの異なる方法があり、誰かが他の人よりも速い:
public static string StripTabsAndNewlines(this string str) {
//string builder (fast)
StringBuilder sb = new StringBuilder(str.Length);
for (int i = 0; i < str.Length; i++) {
if ( ! Char.IsWhiteSpace(s[i])) {
sb.Append();
}
}
return sb.tostring();
//linq (faster ?)
return new string(str.ToCharArray().Where(c => !Char.IsWhiteSpace(c)).ToArray());
//regex (slow)
return Regex.Replace(str, @"\s+", "")
}
String
クラスのTrimEnd()
メソッドを使用してください。あなたは素晴らしい例を見つけることができます こちら
可能であれば、REPLACE( )
関数を使用して、ストアドプロシージャまたはクエリ内のレコードセットのスペースを置き換えることを検討してください。
他の人が述べたように、さまざまなアプローチをプロファイルする必要があります。正規表現を使用している場合は、最低限、クラスレベルの静的変数にする必要があります。
_public static Regex MultipleSpaces = new Regex(@"\s+", RegexOptions.Compiled);
_
emailAddress.Where(x=>{ return x != ' ';}).ToString( )
は関数のオーバーヘッドを持っている可能性がありますが、Microsoftによってインラインに最適化される可能性があります。ここでもプロファイリングにより答えが得られます。
最も効率的な方法は、バッファーを割り当てて、文字ごとに新しいバッファーにコピーし、そのようにスペースをスキップすることです。 C#はポインターをサポートしているため、安全でないコードを使用し、生のバッファーを割り当て、Cのようにポインター演算を使用してコピーできます。これは可能な限り高速です。 SQLのREPLACE( )
は、そのように処理します。
string input =Yourinputstring;
string[] strings = input.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
foreach (string value in strings)
{
string newv= value.Trim();
if (newv.Length > 0)
newline += value + "\r\n";
}
string s = " Your Text ";
string new = s.Replace(" ", string.empty);
// Output:
// "YourText"
これを行う最も高速で一般的な方法(行終端記号、タブも処理されます)。 Regexの強力な機能は、この問題を解決するために実際には必要ありませんが、Regexはパフォーマンスを低下させる可能性があります。
new string
(stringToRemoveWhiteSpaces
.Where
(
c => !char.IsWhiteSpace(c)
)
.ToArray<char>()
)