【问题标题】:What will happen when we access the ' Length ' property of string in C#?当我们在 C# 中访问字符串的“长度”属性时会发生什么?
【发布时间】:2016-01-22 18:22:32
【问题描述】:

示例代码如下:

string hi = "HelloWorld";
int length = hi.Length;
Console.WriteLine(length);
Console.WriteLine(length);
...

string hi = "HelloWorld";
int length = hi.Length;
Console.WriteLine(hi.Length);
Console.WriteLine(hi.Length);
...

如果 string 的 Length 属性会被多次访问,第一个 sn-p 代码是否比第二个更好?为什么?

当我们以 hi.Length 的方式访问字符串的长度时,CLR 会统计 hi 中的字符个数并返回或者只返回一个 10导致 Length 属性在初始化 hi 时被赋值为 10 还是其他原因?

Java 怎么样?

【问题讨论】:

  • @VMA - 不,发帖者在询问调用hi.length 的开销是否值得存储值以供重用
  • 您是否要学习编写 10 万亿段不同代码的“最佳”方法,然后盲目地坚持使用它们,尽管它们可能会影响可读性?优化的第一条规则是:不要。编写简单清晰、易懂的代码,同时设定性能目标。然后衡量你的表现并评估你是否达到了目标。如果还没有,请查明哪里出现性能问题,然后将精力集中在那里。微优化属性访问是非常值得怀疑的。

标签: c# string


【解决方案1】:

Length 是数组的属性(字符串在内部是一个字符数组),这意味着它始终在内存中可用(数组始终是固定长度,因此Length 属性不会改变)。在这两种情况下,您都应该始终只使用 hi.Length 而不是声明另一个变量。现在您只需将长度保存在内存中两次(一次在堆栈上用于 int,一次在堆上用于属性)。

编辑:正如下面的评论者所指出的,此方法针对ICollection 进行了优化,以使用该属性而不是迭代。 如果您使用 linq 方法 .Count(),这将导致您的程序遍历整个数组以计算元素。

【讨论】:

    【解决方案2】:

    您的问题是关于 .NET 在非常低的级别上发生了什么。执行 JIT 和优化的代码时实际发生的情况可能与您的预期不同。

    但是,回答您的问题的一种方法是查看生成的 IL:

    string hi = "HelloWorld";
    int length = hi.Length;
    Console.WriteLine(length);
    Console.WriteLine(length);
    

    编译成

    ldstr       "HelloWorld"
    callvirt    System.String.get_Length
    dup         
    call        System.Console.WriteLine
    call        System.Console.WriteLine
    

    string hi = "HelloWorld";
    Console.WriteLine(hi.Length);
    Console.WriteLine(hi.Length);
    

    (我已经删除了对length 的赋值,因为它没有被使用)编译为

    ldstr       "HelloWorld"
    dup         
    callvirt    System.String.get_Length
    call        System.Console.WriteLine
    callvirt    System.String.get_Length
    call        System.Console.WriteLine
    

    与第二个版本相比,第一个版本的效率似乎稍高一些,因为只有一次调用 System.String.get_Length 并且都使用了额外的堆栈位置 (dup)。然而,JIT'er 可以想象内联这个调用,然后使用间接从内存位置读取值,然后几乎没有任何区别。

    请注意,.NET 字符串类型将字符串的长度存储在字符串对象中,因此无需计算字符串中的字符数。创建字符串时长度是已知的。

    【讨论】:

      【解决方案3】:

      根据MSDN String.Length 是一个属性,它将为您提供当前字符串对象中的字符数。

      在你的情况下,第二个选项相对来说是最好的;因为它可以避免额外的int variable。而且String.Length 不会创建任何实例或额外的内存空间,它会在堆中为字符串返回分配的内存空间。

      【讨论】:

        猜你喜欢
        • 2021-12-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多