2010-05-14 171 views
11

我有人劝我避免反复打电话String.Length,因为每次我打电话时都会重新计算它。我曾假设String.Length在O(1)时间内运行。是String.Length比那更复杂?.NET System.String.Length属性使用什么顺序?

+4

我相信你问的是.NET'System.String.Length'属性,因为C#中没有这样的属性。 – 2010-05-14 17:30:05

+0

相关:http://stackoverflow.com/questions/151472/what-is-the-difference-between-string-empty-and/151481 – 2010-05-14 17:30:51

+1

也相关:http://stackoverflow.com/questions/717801/is- string-length-in-c-net-instant-variable – jball 2010-05-14 17:33:00

回答

20

这是不好的建议 - String.Length确实是O(1)。它不是在C.

喜欢strlen诚然这不是至于我可以告诉保证在the docs,但字符串的不变性使其成为一个非常愚蠢的事情使O(1)。 (而且不只是O(1),而是一个非常快速恒定的时间了。)

坦率地说,如果有人是给那种意见,我会变得有点更加怀疑其他建议他们可能提供太多...

+0

我真的会首先看看上下文,但是说这个调用在循环中有着不必要的上百万次迭代......总的来说,在这些情况下,只是一种好的做法,不要调用一个属性,如果它的整体相同循环。 – eglasius 2010-05-14 17:34:36

+6

@Freddy:我不同意 - 如果它是最简单的代码,并且它正在评估将被内联的非常简单的属性,那么我宁愿这样做,而不是引入临时局部变量。在某些情况下(数组长度),JIT使用属性比使用属性更好,而不是使用临时本地... – 2010-05-14 17:37:27

+0

@Freddy Rios,我不知道,但不会感到惊讶的是编译器知道字符串是不可变的,并且优化了代码相应。我认为这对编译器来说是一个相当简单的优化。 – tster 2010-05-14 17:38:00

2

回想一下,字符串是不可变的。 System.String.Length从未改变。

+9

如果方法需要O(1)时间,这并不回答问题 - 例如,该方法仍然可以是O(n)。 – 2010-05-14 17:34:17

+0

@丹尼尔:这个事实加上常识,再加上有n个人回顾代码,n> 1000,并且假设他们中有1%具有神给大学新生的感觉,几乎是_does_证明该属性运行时间不变。没有数学要求。 – 2010-05-14 18:01:32

4

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

与往常一样,不要开始通过代码缓存对String.Length的所有调用,除非您的配置文件说它是性能问题的来源。

0

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

1

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

为了更进一步,根据.net 框架设计指南,本质上非常静态和非易失性的对象的属性将被设计为属性。如果财产具有波动性,需要在每次通话中重新计算,则应作为方法提供。

当您尝试检查属性是否需要足够的处理周期来吸引您的注意力时,您可以采用此规则。

2

正如其他人所说的String.Length是一个不变的属性。如果你真的关心性能(或者有重要的迭代),你可以将它的值赋给一个本地整型变量一次,并且多次读取(在循环等中)。这会使优化器有更好的机会将此值分配给CPU寄存器。访问一个属性比堆栈变量或寄存器要昂贵得多。

相关问题