(質問者に代わって投稿) .
声をかけてくれた何人かの素晴らしい人々からインスピレーションを得て、問題のコードを分離してテストすることができました.
どちらの場合も、vcard の各「行」の分割を処理する Parser Regex と、エンコードされた 16 進数のキャプチャを処理する Decode Regex があります。
string.Replace を使用するかどうかに関係なく、潜在的な置換 16 進コードを取得するには、Decode Regex に依存する必要があることに気付きました。
数が変化するかどうかを確認するために、いくつかの異なるシナリオを実行しました。以下を含む: Regex MatchCollection をディクショナリにキャストして Match オブジェクトの複雑さを取り除き、Decoding regex を単純な文字列の古い文字列値と新しい文字列値を持つ個別の単純な匿名オブジェクトのコレクションに射影します。
最後に、String.Replace を使用してテストをどのようにマッサージしても、それに近づくことはできましたが、Decoded Regex に置き換えさせるよりも常に遅くなりました。
最も近いものは、速度の約 12% の差でした。
最終的に、好奇心旺盛な人にとっては、これが勝利のコード ブロックになったものです
var ParsedCollection = Parser.Matches(UnfoldedEncodeString).Cast<Match>().Select(m => new
{
Field = m.Groups["FIELD"].Value,
Params = m.Groups["PARAM"].Captures.Cast<Capture>().Select(c => c.Value),
Encoding = m.Groups["ENCODING"].Value,
Content = m.Groups["ENCODING"].Value.FirstOrDefault == 'Q' ? QuotePrintableDecodingParser.Replace(m.Groups["CONTENT"].Value, me => Convert.ToChar(Convert.ToInt32(me.Groups["HEX"].Value, 16)).ToString()) : m.Groups["CONTENT"].Value,
Base64Content = ((m.Groups["ENCODING"].Value.FirstOrDefault() == 'B') ? Convert.FromBase64String(m.Groups["CONTENT"].Value.Trim()) : null)
});
ワンショットで必要なものをすべて与えてくれます。すべてのフィールド、それらの値、任意のパラメーター、および 2 つの最も一般的なエンコーディングがデコードされ、適切にパッケージ化された匿名オブジェクトに投影されます。
プラス面としては、文字列から解析およびデコードされた匿名オブジェクトまでわずか 1000 ナノ秒強です (LINQ および拡張メソッドに感謝します) (約 4,000 の長さの VCARD を使用した 100,000 回のテストに基づく)。