【问题标题】:Most efficient way to determine first character in string?确定字符串中第一个字符的最有效方法?
【发布时间】:2011-12-06 17:36:44
【问题描述】:

这些方法中哪一种是最有效的,或者有更好的方法吗?

this.returnList[i].Title[0].ToString()

this.returnList[i].Title.Substring(0, 1)

【问题讨论】:

  • 这有关系吗?你有性能问题吗?你的基准测试说了什么?
  • 当您回读您的代码时,我会使用对您最有意义的那个。
  • 而且,如果你只是好奇,这是公平的,它很容易衡量。
  • @Oded 我的 C# 职业生涯还很早,知道这些可能会帮助我在未来编写更好的代码。
  • @codekaizen 谢谢,我会调查的。

标签: c# .net substring


【解决方案1】:

他们都非常快:

字符索引

var sample = "sample";
var clock = new Stopwatch();
for (var i = 0; i < 10; i++)
{
    clock.Start();
    for (var j = 0; j < 10000000; j++)
    {
        var first = sample[0].ToString();
    }
    clock.Stop();
    Console.Write(clock.Elapsed);
    clock.Reset();
}

// Results
00:00:00.2012243
00:00:00.2207168
00:00:00.2184807
00:00:00.2258847
00:00:00.2296456
00:00:00.2261465
00:00:00.2120131
00:00:00.2221702
00:00:00.2346083
00:00:00.2330840

子字符串

var sample = "sample";
var clock = new Stopwatch();
for (var i = 0; i < 10; i++)
{
    clock.Start();
    for (var j = 0; j < 10000000; j++)
    {
        var first = sample.Substring(0, 1);
    }
    clock.Stop();
    Console.Write(clock.Elapsed);
    clock.Reset();
}

// Results
00:00:00.3268155
00:00:00.3337077
00:00:00.3439908
00:00:00.3273090
00:00:00.3380794
00:00:00.3400650
00:00:00.3280275
00:00:00.3333719
00:00:00.3295982
00:00:00.3368425

我也同意 BrokenGlass 的观点,即使用 char 索引是一种更简洁的编写方式。另外,如果你做 10 万亿次,它会更快!

【讨论】:

  • 感谢您以如此清晰的方式说明差异!
  • @slinzerthegod 没问题。下载 LINQPad linqpad.net 它是免费的,绝对不可或缺。它将允许您快速轻松地使用和测试 C# 代码。此外,如果答案令人满意地回答了您的问题,请务必检查是否已接受。
【解决方案2】:

您的代码中存在一个可能导致问题的大漏洞,具体取决于您所说的“第一个字符”以及 returnList 包含的内容。

C# 字符串包含 UTF-16,这是一种可变长度编码,如果 returnList 是一个字符串数组,那么 returnList[i] 可能只是一个 Unicode 点的 char。如果要返回字符串的第一个 Unicode 字形:

string s = returnList[i].Title;
if (string.IsNullOrEmpty(s))
    return s;

int charsInGlyph = char.IsSurrogatePair(s, 0) ? 2 : 1;
return s.Substring(0, charsInGlyph);

在使用 BOM、标记和组合字符时,您可能会遇到同样的问题;这些都是有效字符,但如果向用户显示则没有意义。

如果你想要 Unicode 点或字形,而不是字符,你必须使用字符串; Unicode 字形可以是多个字符。

【讨论】:

    【解决方案3】:

    我认为效率方面并不重要,但在我看来,返回第一个字符的更清晰、更惯用且因此更易于维护的方法是使用索引运算符:

    char c = returnList[i].Title[0];
    

    这当然假设至少有一个字符,如果不是给定的,你必须检查它。

    【讨论】:

      【解决方案4】:

      它们的性能应该接近相同。

      该操作的昂贵部分是创建字符串,并且没有更有效的方法来做到这一点。

      除非您想为所有可能的字符预先创建字符串并存储在字典中,但这样一个微不足道的任务会占用大量内存。

      【讨论】:

        【解决方案5】:

        returnList[I].Title[0] 更快,因为它不需要创建新的string,只需要从原始字符中访问一个字符。 当然,如果字符串为空,它会抛出异常,所以你应该先检查一下。

        根据经验,永远不要使用固定长度为 1 的字符串。这就是 char 的用途。

        虽然性能差异可能并不重要,但更好的可读性肯定会。

        【讨论】:

        • 其实你还是需要新建一个字符串,当你把char转回字符串的时候。 (char.ToString())
        • @Charles,为什么不直接比较字符呢? returnList[I].Title[0] = 'A'c
        • @Charles:为什么要将 char 转换回字符串?传递固定长度的 1 字符串没有多大意义......
        • 查看 OP 发布的代码。问题指定在字符上执行 ToString()。
        猜你喜欢
        • 2011-05-02
        • 2011-03-14
        • 2012-03-23
        • 1970-01-01
        • 1970-01-01
        • 2015-08-16
        • 2016-05-02
        • 2018-03-28
        相关资源
        最近更新 更多