【问题标题】:C# Compiler optimization - Unused methodsC# 编译器优化 - 未使用的方法
【发布时间】:2021-07-15 16:30:17
【问题描述】:

C# 编译器(在 VS2008 或 VS2010 中)是否在编译时删除未使用的方法?

我认为它可能无法确定是否会使用公共方法,所以我猜它会编译所有公共方法。

但是从不在类中使用的私有方法呢?

编辑:

是否有一套关于编译器优化的规则记录在任何地方?

【问题讨论】:

  • 注意; 一些编译器,比如用于单点触控的 AOT可能会这样做。

标签: c# visual-studio-2008 visual-studio-2010 optimization compiler-construction


【解决方案1】:

刚刚签入了具有发布版本的反射器。编译器不会删除未使用的私有方法。

有一些方法可以在没有编译器知识的情况下使用方法,例如反射。所以编译器不会试图猜测。它只是将方法留在那里。

编译器删除的唯一私有方法是 partial methods 没有实现。

有关 C# 编译器优化,请查看 here (archive.org)。

【讨论】:

  • 有没有办法在编译器 丢弃未使用的代码的地方进行编译?用例:我想从一个巨大的 3rd 方库中导入 one 函数,并且编译器没有包含所有内容?我认为这通常在 JS/TS 构建中完成(摇树等)。
【解决方案2】:

编译器不会从程序集中剥离任何方法,无论是公共的还是私有的。事实上,我可能会导致奇怪的反射问题,并阻止对此类方法的运行时调用。

有很多框架(如 XAML 解析器)使您能够在没有静态绑定的情况下调用私有方法(想想 XAML 文件中的 OnClick="myFunction")当 OnClick 事件发生时,此标记将调用潜在的私有 myFunction引发...但是编译器在编译时没有关于这种行为的信息。

动态代码也有同样的问题,IL 生成也是如此。在完全信任的情况下执行时,您可以从任何对象访问私有方法。

【讨论】:

    【解决方案3】:

    此优化在 JIT 级别有效实施,这很好,因为它适用于公共/私有/任何方法。如果一个方法从未被调用(忽略 ngen 等),它永远不会被 JITed。现在您可能会说这仍然是对元数据等空间的浪费,但正如其他人指出的那样,私有并不是那么私有。

    【讨论】:

    • 我看不出优化在 JIT 级别上有何价值。核对未使用方法的目的是减少二进制文件的大小。一旦你做了 JITing,二进制文件的大小就不再重要了。
    • 内存中二进制文件的大小也很重要。
    【解决方案4】:

    不,它们不会被删除。它可能会为此发出警告,但不会自行执行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-21
      • 1970-01-01
      • 2017-04-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多