哪种更有效的方法为.NET中的变量赋值?

时间:2008-10-28 01:46:37

标签: .net performance

这是我一直想知道的事情,但从来没有打算过分析。

为temp变量赋值更有效,而不是继续使用该值。一个例子可能更清楚:

string s = reader.GetItem[0].ToString();
someClass.SomeField  = s;
someOtherClass.someField = s;

OR

someClass.SomeField  = reader.GetItem[0].ToString();
someOtherClass.someField = reader.GetItem[0].ToString();

我最初的想法是顶级示例会更高效,因为它不必访问Item集合或调用ToString。

有兴趣听取其他人的想法,或以任何方式确定答案。

8 个答案:

答案 0 :(得分:15)

编译器无法知道右侧的表达式是否有副作用,因此如果您对其进行两次编码,则必须重新评估它。因此,第一个更有效,因为它不会重新做GetItem& ToString调用。

因此,如果程序员知道这些调用是纯/幂等的,那么你应该先编写代码。

答案 1 :(得分:6)

正如Brian所说,第一种方式会更有效率,不过它在现实世界中是否有很大的不同取决于重复功能的价格有多高,以及这段代码作为一个整体被调用的频率如何

然而,除了效率更高之外,第一种方式更好地表明了意图 - 你的意思是为这两件事分配相同的价值。它还有助于维护,因为如果需要更改,您只需要在一个地方进行更改。对我来说,这两者通常比效率更重要。

答案 2 :(得分:2)

还有另一种选择 - 复合作业:

someOtherClass.someField  = someClass.SomeField  = reader.GetItem[0].ToString();

通过这种用法,编译器将评估reader.GetItem[0].ToString() 一次,并使用它来分配给两个成员(它使用get someClass)。它通过复制堆栈上的值(不需要显式本地)来完成此操作。

非常有效,但说实话,我不会对变量的原始内容感到太兴奋。

答案 3 :(得分:0)

假设ToString函数不仅仅发出对某些预先制作的内部对象的引用,那么必须非常清楚的是,第一个版本,只有一个调用它,将是最快的。但是,如果这是一个性能问题,你应该关心与否是一个完全不同的故事。

执行的一个问题是,回想一下,如果从另一个线程同时访问/更改项目,第二个示例可能会在第一行和第二行中呈现不同的结果。

答案 4 :(得分:0)

如果我要多次使用它,我只习惯将值存储在局部变量中。通常,这是因为我更喜欢代码的紧凑性,而不是过于关注效率 - 尽管如果在循环中重复使用它,我肯定会这样做。

有时,我是不一致的,只会重新输入,特别是如果只使用一个访问器而不是调用需要计算的方法。

答案 5 :(得分:0)

这是我的经验法则。如有疑问,profile your code。优化编译器可以删除大量代码,从而使代码运行得更快。

还必须考虑两个事实:

  • .NET非常快速地分配内存。
  • 由于额外的页面错误,参考位置不当,垃圾收集过多,过多的垃圾可能会降低您的应用程序速度。

这意味着粗略观察一下,你的代码可以非常快,但是如果你产生大量垃圾,你的程序的性能会因为运行一段时间而受到影响。

答案 6 :(得分:0)

可读性至关重要。 “s”命名变量有什么用?

此外,不使用[0],而是使用字段名称更有意义。

答案 7 :(得分:0)

还有其他问题需要考虑。如果使用s(分配给其他变量)与s由多行代码初始化的地方分开,则可能会出现其他人出现并稍后添加代码的可能性这改变了s在其使用之间的价值,或以某种方式将原始作业的分支改为s

我看到的很多事情是函数返回变量的赋值,即使该值仅在一个地方使用,我讨厌它,因为(并且这个变量的命名并不重要)这不可避免地导致必须找到分配变量的地方才能知道它真正代表什么。将函数的返回值直接分配给将要使用它的函数,明确指出正在发生的事情。

编程中有一个派系相信“无变量编程”(几十年前着名的“无流程编程”论文)。例如,XSL虽然确实有“变量”,但它们在单个范围内的初始赋值后不可变。有人说,这有助于保证不会出现意外的副作用。