C#编译器会在循环内优化此操作吗?

Will C# compiler optimize this operation inside a loop?
2020-11-21
  •  译文(汉语)
  •  原文(英语)

verticesInnerSides.Length / 2每次以完整的形式在下面的代码之间编写代码的最佳方法是:

for (int i = 0; i < verticesRoof.Length; i++) {
    verticesInnerSides[i * NB_VERTICES + verticesInnerSides.Length / 2] = startInside;
    verticesInnerSides[i * NB_VERTICES + verticesInnerSides.Length / 2 + 1] = startInside + Vector3.up * HEIGHT_ROOF;
    verticesInnerSides[i * NB_VERTICES + verticesInnerSides.Length / 2 + 2] = endInside;
    verticesInnerSides[i * NB_VERTICES + verticesInnerSides.Length / 2 + 3] = endInside + Vector3.up * HEIGHT_ROOF;
}

或以下在循环外编写一次的代码:

myCalculatedVar = verticesInnerSides.Length / 2;
for (int i = 0; i < verticesRoof.Length; i++) {
    verticesInnerSides[i * NB_VERTICES + myCalculatedVar] = startInside;
    verticesInnerSides[i * NB_VERTICES + myCalculatedVar + 1] = startInside + Vector3.up * HEIGHT_ROOF;
    verticesInnerSides[i * NB_VERTICES + myCalculatedVar + 2] = endInside;
    verticesInnerSides[i * NB_VERTICES + myCalculatedVar + 3] = endInside + Vector3.up * HEIGHT_ROOF;
}

C#编译器会在第一种情况下优化此操作吗?

速聊1:
为什么希望编译器为您优化它,而不是首先正确地编写它?
速聊2:
速聊3:
看来您正在使用并行数组反模式.请考虑使用对象和OOP.
速聊4:
.N,大多数优化都应用于CLR层,而不是C#中的IL编译(例如,方法内联).
解决过程1

我认为达​​到可读性和性能的最佳方法是:

myCalculatedVar = verticesInnerSides.Length / 2;
for (int i = 0; i < verticesRoof.Length; i++) {
    int ind = i * NB_VERTICES + myCalculatedVar;
    verticesInnerSides[ind] = startInside;
    verticesInnerSides[ind + 1] = startInside + Vector3.up * HEIGHT_ROOF;
    verticesInnerSides[ind + 2] = endInside;
    verticesInnerSides[ind + 3] = endInside + Vector3.up * HEIGHT_ROOF;
}

但是您可能会浪费时间,并编写一些基准测试来测试这一部分.我确信,如果存在瓶颈,它将位于代码的另一个位置.

解决过程2
  1. 您为什么要像第一个代码示例那样来做呢?第二个(无需查看编译器)似乎更有效.

  2. 根据《代码完成》和许多其他建议:如果不需要,请不要进行优化.

  3. 如果需要,只需进行基准测试即可.(关于基准测试时需要注意的内容,有很多主题,博客和答案,但是我相信您将能够找到它们:)

作为额外的奖励,这是您需要的所有链接的另一个答案:)

速聊1:
我不同意传统观点,即过早的优化"是万恶之源".大多数优化都是免费的(像这样).它们很明显,还可以提高可读性,可维护性和安全性.您只有一个要检查或更改的变量,而不是代码中的多个位置.如果您现在不进行优化,则可能永远也不会对其进行优化.如果您稍后可以看一下代码,那么在不引起任何问题的情况下进行更改就很难理解.
速聊2:
我绝对同意可读性.应编写代码以供阅读.如果完成后遇到性能问题,请找出问题所在,然后对其进行优化.否则,您可能会浪费时间,使代码更难阅读,同时可能会变得更慢.

What is the best approach between the code below where verticesInnerSides.Length / 2 is written in it's complete form each time :

for (int i = 0; i < verticesRoof.Length; i++) {
    verticesInnerSides[i * NB_VERTICES + verticesInnerSides.Length / 2] = startInside;
    verticesInnerSides[i * NB_VERTICES + verticesInnerSides.Length / 2 + 1] = startInside + Vector3.up * HEIGHT_ROOF;
    verticesInnerSides[i * NB_VERTICES + verticesInnerSides.Length / 2 + 2] = endInside;
    verticesInnerSides[i * NB_VERTICES + verticesInnerSides.Length / 2 + 3] = endInside + Vector3.up * HEIGHT_ROOF;
}

Or the following where it's written outside the loop once :

myCalculatedVar = verticesInnerSides.Length / 2;
for (int i = 0; i < verticesRoof.Length; i++) {
    verticesInnerSides[i * NB_VERTICES + myCalculatedVar] = startInside;
    verticesInnerSides[i * NB_VERTICES + myCalculatedVar + 1] = startInside + Vector3.up * HEIGHT_ROOF;
    verticesInnerSides[i * NB_VERTICES + myCalculatedVar + 2] = endInside;
    verticesInnerSides[i * NB_VERTICES + myCalculatedVar + 3] = endInside + Vector3.up * HEIGHT_ROOF;
}

Will C# compiler optimize this operation in the first case ?

Talk1:
Why hope the compiler optimizes it for you instead off writing it properly in the first place?
Talk2:
open ILDSM and check for yourself <br/> msdn.microsoft.com/en-us/library/aa309387(v=vs.71).aspx
Talk3:
It appears you are using the parallel array anti pattern. Please consider using objects and OOP.
Talk4:
.N, most optimizations applied at CLR layer, not at C# to IL compilation (method inlining for example).
Solutions1

In my opinion the best way to reach readability and performance is:

myCalculatedVar = verticesInnerSides.Length / 2;
for (int i = 0; i < verticesRoof.Length; i++) {
    int ind = i * NB_VERTICES + myCalculatedVar;
    verticesInnerSides[ind] = startInside;
    verticesInnerSides[ind + 1] = startInside + Vector3.up * HEIGHT_ROOF;
    verticesInnerSides[ind + 2] = endInside;
    verticesInnerSides[ind + 3] = endInside + Vector3.up * HEIGHT_ROOF;
}

But you can waste your time and write some benchmarks test for testing this piece. I am sure that if a bottleneck will exist it will be in another place in the code.

Solutions2
  1. Why would you do it like the first code example to begin with ? The second one (without looking at the compiler) seems more efficient.

  2. As per Code Complete, and many other suggestions: Don't optimize if you don't need to.

  3. If you need to, simply benchmark. (There's plenty of threads, blogs and answers about what to look out for when benchmarking, but I'm sure you'll be able to find them :)

As an extra bonus, here's another answer with all the links you'll need :)

Talk1:
I don't agree with the conventional wisdom that pre-mature optimization "is the root of all evil". Most optimizations come with no cost (like this). They are obvious and also can increase readability, maintainability and safeness. You only have one variable to check or change instead of multiple places in the code. If you don't optimize now, you'll probably never optimize it. It's much more difficult to understand if you can change something without causing problems if you look at the code later.
Talk2:
I absolutely agree about readability. Code should be written to be read. If when you're done, you have a performance issue, find out where, and then optimize that bit. Otherwise, you might be wasting time and making your code harder to read, and at the same time, maybe even slower.
转载于:https://stackoverflow.com/questions/28361370/will-c-sharp-compiler-optimize-this-operation-inside-a-loop

本人是.net程序员,因为英语不行,使用工具翻译,希望对有需要的人有所帮助
如果本文质量不好,还请谅解,毕竟这些操作还是比较费时的,英语较好的可以看原文

留言回复
我们只提供高质量资源,素材,源码,坚持 下了就能用 原则,让客户花了钱觉得值
上班时间 : 周一至周五9:00-17:30 期待您的加入