C# .NET System.String.Length属性的时间顺序是什么?

C# .NET System.String.Length属性的时间顺序是什么?,c#,.net,string,complexity-theory,big-o,C#,.net,String,Complexity Theory,Big O,有人建议我避免重复调用String.Length,因为每次调用时都会重新计算它。我假设String.Length在O(1)时间内运行。String.Length比这更复杂吗?回想一下字符串是不可变的System.String.Length永远不会更改。这是个错误的建议-String.Length确实是O(1)。它不像C中的strlen 诚然,就我所知,这并不能保证,但是字符串的不变性使得不生成O(1)是一件非常愚蠢的事情。(不仅仅是O(1),还有一个非常快的恒定时间。) 坦白地说,如果有人给出这

有人建议我避免重复调用
String.Length
,因为每次调用时都会重新计算它。我假设
String.Length
在O(1)时间内运行。
String.Length
比这更复杂吗?

回想一下字符串是不可变的
System.String.Length
永远不会更改。

这是个错误的建议-
String.Length
确实是O(1)。它不像C中的strlen

诚然,就我所知,这并不能保证,但是字符串的不变性使得不生成O(1)是一件非常愚蠢的事情。(不仅仅是O(1),还有一个非常快的恒定时间。)

坦白地说,如果有人给出这种建议,我会对他们可能提供的其他建议更加怀疑…

String.Length是O(1)。人们告诉您不要在循环中调用它的原因是因为它是一个属性访问,与方法调用相同。实际上,一个额外的方法调用很少会产生任何显著的差异


和往常一样,不要开始检查代码缓存对String.Length的所有调用,除非探查器说这是性能问题的根源。

根据内部注释,String.Length属性是一条不运行for循环的指令。因此,它是一个O(1)操作。

否它不会重新计算。字符串类型是不可变的

为了进一步说明这一点,根据.net框架设计指南,本质上非常静态和非易失性的对象的属性将被设计为属性。如果属性具有易失性,需要在每次调用时重新计算,则应将其作为方法提供


您可以在尝试检查某个属性是否需要足够的处理周期来吸引您的注意时使用此规则。

正如其他人所说的字符串。长度是一个常量属性。如果您真的关心性能(或有重要的迭代),您可以将其值分配给局部整数变量一次,然后读取多次(在循环中,等等)。这将使优化器有更好的机会将该值分配给CPU寄存器。访问属性是一个比堆栈变量或寄存器更昂贵的操作。

我想你是在问.NET
System.String.Length
属性,因为C#中没有这样的属性。相关:也相关:约翰·桑德斯:是的,我是说System.String.Length。谢谢你的修复。有什么特别的理由说全名(System.String.Length)而不仅仅是String.Length吗?编辑:哦,我想你的意思是因为System.String是.NET的一部分,而不是C语言。访问String.Length比访问局部变量慢得多。如果你有一个很紧的循环,你要访问它数十亿次,并且你想缩短几秒钟,你就应该担心它。在我的机器上,string.Length和局部变量之间的差异约为1.4纳秒。不管字符串是50个字符还是5000万个字符都没有区别。如果该方法需要O(1)个时间,这并不能回答这个问题-例如,该方法仍然可以是O(n)。不过,我真的会先看看上下文,说调用不必要地处于一个循环中,有数百万次迭代。。。总的来说,在这些情况下,如果整个循环都是相同的,那么不调用属性就是一种很好的做法。@Freddy:我不同意-如果它是最简单的代码,并且它正在计算一个非常简单的将要内联的属性,我宁愿这样做,而不是引入一个临时局部变量。在某些情况下(数组长度),JIT使用该属性比使用临时本地…@Freddy Rios做得更好,我不知道,但编译器知道字符串是不可变的,并相应地优化代码,这并不奇怪。我认为,对于编译器来说,这将是一个相当简单的优化。