【发布时间】:2012-04-27 01:00:25
【问题描述】:
这是some other question 中讨论的衍生产品。
假设我必须解析大量非常长的字符串。每个字符串都包含一个由空格分隔的doubles 序列(当然是文本表示)。我需要将doubles 解析为List<double>。
标准解析技术(使用string.Split + double.TryParse)似乎很慢:我们需要为每个数字分配一个字符串。
我尝试使它成为类似 C 的旧方式:计算包含数字的子字符串的开头和结尾的索引,并“就地”解析它,而不创建额外的字符串。 (见http://ideone.com/Op6h0,下图为相关部分。)
int startIdx, endIdx = 0;
while(true)
{
startIdx = endIdx;
// no find_first_not_of in C#
while (startIdx < s.Length && s[startIdx] == ' ') startIdx++;
if (startIdx == s.Length) break;
endIdx = s.IndexOf(' ', startIdx);
if (endIdx == -1) endIdx = s.Length;
// how to extract a double here?
}
string.IndexOf 的重载,只在给定的子字符串中搜索,但我没有找到从子字符串中解析双精度的方法,而没有先实际提取该子字符串。
有人有想法吗?
【问题讨论】:
-
你有没有证明这实际上是一个瓶颈?我不知道有什么方法可以临时做,但我当然希望在微优化之前有一些证据证明它是一个问题。
-
@Jon:不是真的。该问题基于链接问题 (stackoverflow.com/questions/10053449/…) 的讨论。很抱歉。
-
很公平。我怀疑手写的解析例程会比 BCL 团队提出的可能经过大量经验优化的方法要慢:)
-
@Henk:非常感谢您的建议——但我会避免进一步讨论,因为它似乎从编码问题变成了个人问题。
-
@HenkHolterman 你可能是对的,在许多用例中这是一个无关紧要的过早优化。在我们的案例中,我们无法轻松地将大量数据预处理为更合理的格式,并且我们需要在有限的平台上加载它,我们看到由于 GC 直接由 string.Split 中的分配引起的显着开销。问题背后的问题与我们非常相关,我相信这也是在 C# 7.2 中引入 Span
的原因之一。