即使更冗长,在 foreach 之外定义变量是否是更好的编码实践?

发布于 2024-08-24 18:46:57 字数 1526 浏览 9 评论 0原文

在以下示例中:

  • 第一个看起来更冗长,但不那么浪费资源,
  • 第二个不太冗长,但更浪费资源(每个循环重新定义字符串)

哪个是更好的编码实践?

第一个示例:

using System;
using System.Collections.Generic;

namespace TestForeach23434
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> names = new List<string> { "one", "two", "two", "three", "four", "four" };

            string test1 = "";
            string test2 = "";
            string test3 = "";
            foreach (var name in names)
            {
                test1 = name + "1";
                test2 = name + "2";
                test3 = name + "3";
                Console.WriteLine("{0}, {1}, {2}", test1, test2, test3);
            }
            Console.ReadLine();
        }
    }
}

第二个示例:

using System;
using System.Collections.Generic;

namespace TestForeach23434
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> names = new List<string> { "one", "two", "two", "three", "four", "four" };

            foreach (var name in names)
            {
                string test1 = name + "1";
                string test2 = name + "2";
                string test3 = name + "3";
                Console.WriteLine("{0}, {1}, {2}", test1, test2, test3);
            }
            Console.ReadLine();
        }
    }
}

In the following examples:

  • the first seems more verbose but less wasteful of resources
  • the second is less verbose but more wasteful of resources (redefines string each loop)

Which is better coding practice?

First example:

using System;
using System.Collections.Generic;

namespace TestForeach23434
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> names = new List<string> { "one", "two", "two", "three", "four", "four" };

            string test1 = "";
            string test2 = "";
            string test3 = "";
            foreach (var name in names)
            {
                test1 = name + "1";
                test2 = name + "2";
                test3 = name + "3";
                Console.WriteLine("{0}, {1}, {2}", test1, test2, test3);
            }
            Console.ReadLine();
        }
    }
}

Second example:

using System;
using System.Collections.Generic;

namespace TestForeach23434
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> names = new List<string> { "one", "two", "two", "three", "four", "four" };

            foreach (var name in names)
            {
                string test1 = name + "1";
                string test2 = name + "2";
                string test3 = name + "3";
                Console.WriteLine("{0}, {1}, {2}", test1, test2, test3);
            }
            Console.ReadLine();
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

如梦初醒的夏天 2024-08-31 18:46:57

第二种形式不再浪费——它只是更好。

在循环外部声明变量没有任何优势,除非您想在迭代之间维护它们的值。

(请注意,通常这不会造成行为差异,但如果变量由 lambda 表达式或匿名方法捕获,则情况并非如此。)

The second form is no more wasteful - it's simply better.

There's no advantage to declaring the variables outside the loop, unless you want to maintain their values between iterations.

(Note that usually this makes no behavioural difference, but that's not true if the variables are being captured by a lambda expression or anonymous method.)

不必了 2024-08-31 18:46:57

就我个人而言,我认为考虑到变量的用途,最好的做法是在尽可能严格的范围内声明变量。

这提供了许多好处:

  1. 重构更容易,因为当变量已经在同一范围内时提取方法更简单。
  2. 变量的使用更加清晰,这将导致代码更加可靠。

唯一(潜在的)缺点是额外的变量声明 - 然而,JIT 倾向于优化这个问题,所以这是我在实际工作中不一定担心的问题。

唯一的例外是:

如果您的变量将增加大量 GC 压力,并且如果可以通过 foreach/for 循环重用相同的对象实例来避免这种情况,并且 如果 GC 压力导致测量性能问题,我会将其提升到外部范围。

Personally, I think it's the best practice to declare variables in the tightest scope possible, given their usage.

This provides many benefits:

  1. It's easier for refactoring, since extracting a method is simpler when the variables are already in the same scope.
  2. The variable usage is more clear, which will lead to more reliable code.

The only (potential) disadvantage would be the extra variable declaration - however, the JIT tends to optimize this issue away, so it's one I wouldn't necessarily worry about in real work.

The one exception to this:

If your variable is going to be adding a lot of GC pressure, and if this can be avoided by reusing the same object instance through the foreach/for loop, and if the GC pressure is causing measured performance problems, I'd lift it into the outer scope.

雪落纷纷 2024-08-31 18:46:57

这些既浪费又冗长。

foreach (var name in names)
{
   Console.WriteLine("{0}1, {0}2, {0}3", name);
}

</tongueincheek>

Those are both wasteful and verbose.

foreach (var name in names)
{
   Console.WriteLine("{0}1, {0}2, {0}3", name);
}

.

</tongueincheek>
烟织青萝梦 2024-08-31 18:46:57

根据语言和编译器的不同,它可能相同也可能不同。对于 C#,我希望生成的代码非常相似。

我自己的理念很简单:

为了易于理解而优化。

任何其他的都是过早的优化!大多数开发中最大的瓶颈是开发人员的时间和注意力。如果您绝对必须挤出最后一个 CPU 周期,那么请务必这样做,但除非您有令人信服的业务需要去做或正在编写关键组件(公共库、操作系统内核等),否则最好等到您可以对完成的程序进行基准测试。那时优化一些成本最高的例程是合理的,在此之前几乎肯定是浪费时间。

Depending on language and compiler it may or may not be the same. For C# I expect the resulting code to be very similar.

My own philosophy on this is simple:

Optimize for ease of understanding.

Anything else is premature optimization! The biggest bottleneck in most development is time and attention of the developer. If you absolutely must squeeze out every last CPU cycle then by all means do so, but unless you have a compelling business need to do or are writing a critical component (common library, operating system kernel, etc) you are better off waiting until you can benchmark the finished program. At that time optimizing a few of the most costly routines is justified, before then it's almost certainly a waste of time.

终陌 2024-08-31 18:46:57

我不确定通过在循环之外定义字符串变量会得到什么。字符串是不可变的,因此不会被重用。每当您分配给它们时,都会创建一个新实例。

I'm not sure what you gain by defining the string variable outside of the loop. Strings are immutable so they are not reused. Whenever you assign to them, a new instance is created.

梓梦 2024-08-31 18:46:57

我认为这取决于你想解决什么问题。我喜欢第二个示例,因为您可以一步移动代码。我喜欢第一个示例,因为它的速度更快,因为堆栈操作更少,内存碎片更少,对象构造/创建更少。

I think it depends on what you are trying to solve. I like the second example, because you can move the code in one step. I like the first example, because it is faster due to less stack manipulations, less memory fragmentation, and less object construction/creation.

つ低調成傷 2024-08-31 18:46:57

我发现将声明“提升”到循环之外通常是更好的长期维护策略。编译器通常会以可接受的方式进行排序以提高性能。

I've found that 'hoisting' declarations out of loops is typically a better long-term strategy for maintenance. The compiler will usually sort things out acceptably for performance.

猫烠⑼条掵仅有一顆心 2024-08-31 18:46:57

就性能而言,它们实际上是相同的(字符串是不可变的),但就可读性而言......我想说两者都不是很好。您可以轻松地在 Console.WriteLine 中完成这一切。

也许您可以发布真正的问题而不是示例?

They are both virtually the same as far as performance goes (strings are immutable), but as for readability... I'd say neither is very good. You could easily just do it all within the Console.WriteLine.

Perhaps you can post the real problem instead of an example?

全部不再 2024-08-31 18:46:57

我通常会在范围允许的范围内声明尽可能接近其用途的变量,在本例中这将是您的第二个示例。 Resharper 也倾向于鼓励这种风格。

I generally declare variables as close to their use as scoping allows, which in this case would be your second example. Resharper tends to encourage this style as well.

迷荒 2024-08-31 18:46:57

对于 POD 类型数据,声明最接近首次使用。对于诸如执行任何内存分配的类之类的任何内容,您应该考虑在任何循环之外声明它们。字符串几乎肯定会进行某种形式的分配,并且大多数实现(至少在 C++ 中)将在可能的情况下尝试重用内存。基于堆的分配确实可能非常慢。

我曾经分析过一些 C++ 代码,其中包含一个在其构造函数中新增数据的类。在循环外部声明变量的运行速度比在循环内部声明变量的运行速度快 17%。 C# 中的 YMMV 因此分析性能您可能会对结果感到非常惊讶。

For POD type data declare closest to first use. For anything like a class that does any memory allocation, then you should consider declaring those outside of any loops. Strings will almost certainly do some form of allocation and most implementations (at least in C++) will attempt to reuse memory if possible. Heap based allocations can be very slow indeed.

I once profiled a bit of C++ code that included a class that new'd data in its ctor. With the variable declared outside of the loop it ran 17% faster than with the variable declared inside the loop. YMMV in C# so profile performance you may be very surprised at the results.

っ〆星空下的拥抱 2024-08-31 18:46:57

这是 Linq 我最喜欢的部分,我想它适合这里:

names.ForEach(x => Console.WriteLine("{0}1, {0}2, {0}3", x));

This is my favourite part of Linq which I guess it fits here:

names.ForEach(x => Console.WriteLine("{0}1, {0}2, {0}3", x));
烈酒灼喉 2024-08-31 18:46:57

声明变量时遵循简单的规则

在第一次需要时声明它

Follow a simple rule while declaring variables

Declare it when you need it for the first time

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文