我可以让 .net 编译器进行一些乐观缓存来加速构建而不将代码库重构为程序集吗?

问题描述 投票:0回答:3

我的 dotnet 代码库相当大(所以我不想在程序集项目中进行重构),但并没有改变那么多。尽管磁盘速度很好,但构建确实很慢 - 显然只需要一段时间即可编译该东西。因此,恕我直言,编译器缓存自上次构建以来未更改的文件的编译版本是很有意义的,因为乐观地期望另一个文件中的更改不会破坏模块。然后,如果乐观的假设被证明无效,则可以进行完整的构建。嗯,我很确定在使用 Java 和 C++ 编译器时经常会发生类似的事情。

可以在 dotnet 中完成类似的事情吗?如果没有,为什么不:-) ?

.net caching build
3个回答
4
投票

除非必要,否则 Visual Studio 不会重建程序集。当以下任何一项发生变化时,它“必须”:

  • 程序集属性,例如目标 CPU/框架
  • 引用的程序集中的依赖关系(如果程序集 A 中的对象 A1 需要 B 中的 B1,并且 B1 发生更改,则必须重新构建程序集 A 和 B)
  • 将编译到程序集中的源代码(显然)

此外,构建速度不太依赖于纯粹的代码数量,甚至类数量,而是依赖于正在构建的项目数量。考虑到必须完全重建的代码行数恒定,构建到一个程序集中的解决方案将比构建到 10 个程序集的解决方案构建得更快,因为构建在每个程序集中重复的程序集会产生大量固有开销。组装。

以下是一些提高构建速度的基本技巧:

  • 尝试将更改保持在程序集引用层次结构中尽可能“高”的级别。当 A 依赖于 B 并且 B 依赖于 C 时,如果 A 发生变化,则只需重建 A,但如果 B 或 C 发生变化,则也必须重建更高的任何东西。这并不总是可能的,但减少程序集的数量将减少这一层次结构,因此即使您必须重建较低的程序集,依赖它的其他程序集也会减少。
  • 通过使用任何跨程序集依赖项的接口来松散耦合您的代码,并将接口隔离到它们自己的程序集中。如果 B 类发生变化,依赖于 B 类的 A 类将必须重新构建。但是,如果 A 依赖于 B 实现的接口 I,则如果 B 发生更改,则不必重新构建 A;只有当我这样做时(这种情况很少见)。然而,VS 构建程序集;如果我与 B 位于程序集中,则即使 B 发生更改,包含 A 的程序集也必须重建,即使我没有更改。
  • 创建仅构建该配置绝对必需的内容的构建配置。调试版本不应重建安装程序。出于同样的原因,发布版本不应重建测试程序集。但是,默认情况下,新项目被设置为包含在每个构建配置中,因此您必须定期维护这些配置。
  • 在安装程序方面,看看是否可以将其单独构建为一个配置。安装程序很容易成为任何解决方案重建中最慢的单一构建;首先,他们仔细检查所有程序集是否已构建,然后收集需要包含的所有内容并将其存档到 CAB 中,然后将其与 MSI 中的安装逻辑封装在一起。除非您实际上正在生成候选版本,否则请避免构建此版本。
  • 仅在必要时才执行“重建解决方案”。重建解决方案执行“清理”和“构建”,导致所有内容都必须重新创建。
  • 最大限度地减少构建后操作。与创建删除不需要的程序集的配置类似,创建允许您在不需要时跳过构建后操作的配置,或者简单地重新安排您的解决方案,以便构建最终在正确的位置开始,将大大加快您的速度。
  • 当您重建、重新分析新程序集、确定更改等时,ReSharper 或 SVN 客户端等工具以及索引帮助程序会变得疯狂。确保 Windows 索引服务不会索引您的源代码目录或任何构建输出位置,请关闭 ReSharper 解决方案分析,并且不要将构建输出包含在 SVN 版本控制中。

1
投票

我假设您使用 Visual Studio 并将所有项目都放在一个解决方案中?在这种情况下,编译器通常只构建发生更改的项目以及依赖于它们的项目。

如果将所有代码编译到一个程序集中(解决方案中只有一个项目),则编译器不会缓存任何内容。每个 Dll 始终完全从其所有源构建。没有像 C/C++ 那样的目标文件。

在这种情况下,正确的方法是将代码分解为多个程序集(每个类一个程序集是经验法则/最佳实践)。


0
投票

简单。将代码拆分为多个较小的项目/程序集。如果没有检测到更改,它们将不会被重新编译。在源文件级别,这是几乎不可能的,因为源文件几乎不是独立的代码单元

© www.soinside.com 2019 - 2024. All rights reserved.