【发布时间】:2020-11-14 01:07:52
【问题描述】:
Joe Duffy's Blog 意味着使用string.Substring 比string.Split 更有效。
我不知道它是否说 Substring 方法没有分配新字符串,或者它是否更有效,因为它不会进行任何不需要的分配。你能解释一下它是如何更有效的并举个例子吗?
我理解他的第一个例子是创建一个数组,然后处理数组中的每个字符串。
string str = ...;
string[] substrs = str.Split(',');
foreach (string subtr in substrs) {
Process(substr);
}
以下如何更高效
string str = ...;
int lastIndex = 0;
int commaIndex;
while ((commaIndex = str.IndexOf(',', commaIndex)) != -1) {
Process(substr, lastIndex, commaIndex);
lastIndex = commaIndex + 1;
我看到的是使用String.IndexOf 查找逗号的索引,然后处理字符串。我假设他打算在处理过程中使用String.Substring 来提取数据。下面的一位 cmets 建议他可能会逐个字符地拉它。他会一直拉字符,直到他击中下一个逗号,可能会构建一个字符数组?
【问题讨论】:
-
是的 sting.Index of 用于查找逗号的索引,但在您假设的处理方法中,您仍然需要创建一个子字符串来提取这些索引中的数据。对吗?
-
我的立场是正确的 - 这个例子确实令人困惑
-
“那里潜伏着地雷 API,比如 String.Split 和 String.Substring”暗示他认为
Substring效率不高。而且我认为“String毕竟有一个索引器。而且它是类型安全的!所以就地解析至少不会导致缓冲区溢出”意味着他打算让你逐个字符地访问子字符串,而不是使用Substring。 -
@GrimR3:您不需要创建子字符串来访问数据,但如果您不这样做,您想要做的一切都会变得更加复杂。您将无法再访问最初使字符串有用的大部分内容,例如
Trim*、StartsWith、EndsWith,以及一般的直接比较。 (例如,substr == "stuff"变为(end - start) == 5 && String.Compare(str, start, "stuff", 0, 5) == 0。)您必须自己完成所有这些操作,而且您可能会在此过程中搞砸很多。请注意,作者自己的示例无法编译。 :P -
@Blorgbeard:
Substring没有达到应有的效率。我看到的代码似乎表明它总是创建一个包含字符副本的新数组,而不是像 Java 那样使用范围引用原始字符串的数组。 Java 方式的缺点是longString.substring(0, 2)可以将longString的整个后备数组保留在内存中,即使在longString死后您只使用它的两个字符。