2017-09-02 66 views
2

我通常使用C++和Rust等零成本抽象概念进行编程。C#是否具有零成本抽象?

目前我在使用C#语言的一个项目我工作。所以我想知道是否可以安全地创建抽象和更高级别的代码而不影响性能。

这有可能在C#或性能关键代码,我应该只是做低级别代码可能吗?作为我在代码中遇到的一个例子(不要太在意这个例子,我的问题是更高级的),我需要一个函数来返回多个值,为此,我的第一个方法是使用元组,所以这样的事情:

public (int, int, float) Function(); 

或摘要本解析成一个结构:

public struct Abstraction { int value1; int value2; float value3; }; 

public Abstraction Function(); 

我预料的是,编译器将优化TupleAbstraction struct路程,只需使用原始值直接。但我发现的是,写的用out参数代码将提高性能:

public void Function(out int value1, out int value2, out float value3); 

我猜测的原因是因为在out功能,没有TupleAbstraction struct创作。

out功能版本的问题是,我真的很讨厌用参数,返回值,因为它似乎更像是一个破解到语言限制。

那么,到底我不知道如果我只是没有使用正确的配置,因此JIT可以用零成本的抽象或者这根本就是不可能的,或者在C#中不能保证。

+0

这看起来像是微型优化。使用一种方法而不使用另一种方法的性能成本可能可以忽略不计,并且与算法本身的整体性能相比可能无关紧要。 –

+1

结构本身就是一个抽象。如果方法不能内联,那么抖动会将方法重写为void Function(out Abstraction retval)。就像C或C++编译器必须这样做。有很多糟糕的基准测试,这是非常快速的代码,很难衡量。 –

回答

1

当你返回的东西,你总是创建一个新的对象 - 你完全保存这一步时,只是工作“到位”与您out参数。然后,你有你的编译器不能简单优化的东西 - 我不得不告诉你一些关于C中严格的别名规则,但我不知道C#足以知道类似的东西是否适用于这里。

所以,一般地,创建元组或Abstraction类型的对象是不可优化了。您明确指定要返回该类型的对象,以便该对象必须由该函数的“常规”编译创建。你可以说,编译器知道在Function被称为背景和可以推断,它是确定不生成对象,而是直接工作,就好像这些是参考你要以后分配的Abstraction领域的事情,但在这里重叠规则可能会变得非常复杂,而且这通常在逻辑上是不可能的。

相关问题