使成员私有或内部帮助编译器进行优化吗?

Nic*_*pat 0 .net c#

我正在阅读Eric Lippert的帖子

http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx

所以我想知道开发人员可以做些什么来帮助C#编译器进行优化,例如使用堆栈而不是堆.例如,如果您在程序集内部创建属性而不是protected/public,则编译器可以考虑保证在程序集外部不会看到该属性,因此不可能引用该属性.

class Foo {
    internal Object Bar;
}
Run Code Online (Sandbox Code Playgroud)

显然,在优化编译器和编写实际上比QA /单元测试要求更正确的代码之间存在一条细线,以帮助编译器对其做出更强的假设.

我也想知道其他什么可以帮助优化器,并且在增加正确性的意义上也值得付出努力.

Eri*_*ert 9

我想知道开发人员可以做些什么来帮助C#编译器进行优化,例如使用堆栈而不是堆.

这是一个崇高的目标,但你会向后看.而不是说"如何编写我的程序来帮助编译器生成良好的代码?" 问"我的程序难以接受吗?" 如果它然后使用分析器找到最慢的部分,然后找出它为什么这么慢,然后问"我该怎么做才能使这段代码更快?"

例如:在Roslyn中,我们发现编译器的大部分时间成本与在语义分析期间创建的数以万计的临时对象的垃圾收集相关联.我们决定使用各种技术来解决这个问题,例如池策略,延迟分配,仔细调整的缓存以及允许丢弃大对象的架构,并在必要时根据需要重新计算.

我们的态度始终是"我们必须确保这是快速的",但我们确保的方式不是试图预先编写程序以加快速度.相反,我们所做的是很早就编写了一个性能测试套件,以便我们可以每天监控昨天的签入是否引入了性能回归; 这使我们能够快速了解​​哪些技术正在进行改进以及哪些技术正在进行回归.

性能是一项功能,因此可以像任何其他功能一样进行设计.设定目标,编写测试以验证您是否达到了这些目标.编写快速代码的"提示和技巧"通常毫无价值; 表现出来的的过程中使用好经验的工程技术.

解决您的具体问题:

使成员私有或内部帮助编译器进行优化吗?

这个问题预先假定你将公共财产变为私有财产,因为它更快.但是房产是公开的,因为客户需要使用它.将成员设为私有的原因是因为它是类的实现细节,而不是因为编译器可能能够找到优化.

有几种方法可以帮助编译器进行非常小的优化.例如:

class Fruit {}
class Apple : Fruit {}
class Orange : Fruit {}
...
Fruit[] fruits = new Apple[10];
Run Code Online (Sandbox Code Playgroud)

哦痛苦.C#支持不安全的数组协方差.当你说

fruits[0] = new Apple();
Run Code Online (Sandbox Code Playgroud)

运行时必须生成一个检查,说" fruits实际上是一个Orange[]?因为如果是,我们需要抛出一个异常." 这是不可避免的.现在考虑:

Apple[] apples = MakeAppleArray();
apples[0] = someApple;
Run Code Online (Sandbox Code Playgroud)

现在,这里是否还需要运行时检查?是.apples可能是GrannySmith[]someApple可能是RedDelicious,所以检查是必要的.但是假设你说

sealed class Apple : Fruit {}
Run Code Online (Sandbox Code Playgroud)

现在运行时知道apples不可能真的是GrannySmith[]因为没有这样的类型.通过知道密封可能可以节省几纳秒Apple.

再次,节省几纳秒并不是密封课程的好理由.表达该课程不是为进一步继承而设计的意图是密封课程的原因.

同样,如果编译器看到

X M() { return new X(); }
...
M().Foo(); // instance method
Run Code Online (Sandbox Code Playgroud)

然后编译器将生成代码,检查M()是否在调用实例方法Foo之前​​返回null,因为它不够聪明,不能认识到M()永远不会返回null.但如果你说

(new X()).Foo();
Run Code Online (Sandbox Code Playgroud)

那么编译器会说"这会抛出或产生一个有效的引用,因此可以删除空检查".编译器在这里聪明.以第二种方式而不是第一种方式编写代码可以节省多达两或三纳秒.这不值得.不要编写代码来试图利用编译器的小技巧; 你永远不会注意到差异. 应用商店中没有销售一百万份的程序,因为他们省略了空检查并节省了一纳秒.