(代表问题作者发布)。
从一些插话的好人那里得到一些启发,我设法隔离并测试了有问题的代码。
在这两种情况下,我都有一个解析器正则表达式来处理分解电子卡的每一“行”,以及一个解码正则表达式来处理捕获任何编码的十六进制数字。
我突然想到,无论我是否使用 string.Replace,我仍然必须依靠 Decode Regex 来获取潜在的替换十六进制代码。
我经历了几个不同的场景,看看数字是否会改变;包括:将 Regex MatchCollection 转换为 Dictionary 以消除 Match 对象的复杂性,并将 Decoding 正则表达式投影到具有旧字符串值和新字符串值的不同简单匿名对象的集合中。替换调用
最后,无论我如何使用 String.Replace 按摩测试,它都接近但总是比让解码的正则表达式做它的替换事情慢。
最接近的是大约 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)
});
一口气给了我我需要的一切。所有字段、它们的值、任何参数以及解码后的两种最常见的编码都投射到一个很好打包的匿名对象中。
从好的方面来说,从字符串到解析和解码的匿名对象只有 1000 多纳秒(感谢 LINQ 和扩展方法)(基于 100,000 次测试和大约 4,000 长度的 VCARD)。