GenerateResource / CoreResGen 突然花费了近 30 倍的时间
从几周前开始,编译一个项目(VB.NET、.NET 2.0、VS 2010)的时间是以前的好几倍。在任务管理器中,我注意到 ResXtoResources.exe
占用了大量 CPU 一段时间。我终于能够使用 MSBuild 的“诊断”输出设置获得一些相关数据,并将该输出与我几个月前在分支中看到的内容进行比较。最引人注目的是最后几行,它给出了时间。之前:
Target Performance Summary:
[..]
1395 ms CoreResGen 1 calls
1930 ms CompileLicxFiles 1 calls
2135 ms GenerateApplicationManifest 1 calls
2844 ms CoreCompile 1 calls
Task Performance Summary:
[..]
1391 ms GenerateResource 1 calls
1929 ms LC 1 calls
2134 ms GenerateApplicationManifest 1 calls
2843 ms Vbc 1 calls
Build succeeded.
Time Elapsed 00:00:09.50
========== Rebuild All: 5 succeeded, 0 failed, 0 skipped ==========
之后:
Target Performance Summary:
1348 ms CompileLicxFiles 1 calls
1747 ms GenerateApplicationManifest 1 calls
2595 ms CoreCompile 1 calls
39575 ms CoreResGen 1 calls
Task Performance Summary:
1347 ms LC 1 calls
1745 ms GenerateApplicationManifest 1 calls
2593 ms Vbc 1 calls
39570 ms GenerateResource 1 calls
Build succeeded.
Time Elapsed 00:00:47.34
========== Rebuild All: 5 succeeded, 0 failed, 0 skipped ==========
两个项目都是在同一系统上使用相同的设置进行编译的。当然,我们已经做了很多改变,但没有任何改变足以证明时间上的这种改变是合理的(而且仅针对这一项任务!)。我认为资源生成陷入了困境——循环引用、缺失引用等。但是,我一直无法找到任何有用的信息来跟踪此类问题,直到我认为只是一个资源文件。
除了查看数千个签入或暂时从项目中删除某些表单(以及它们的资源文件)之外,我还能做些什么来找出问题吗?我似乎无法找到单独的每个资源文件的计时。
到目前为止的发现:
我创建了一个新的空项目,其中包含所有相同的 .resx
文件。
- 该问题在 .NET 4.0 中无法重现:编译完全相同的测试项目只需不到一秒的时间。
- 一旦我添加了原始项目中的一个表单,该问题就可以在 .NET 2.0 中重现;显然,否则它将无法“正确”编译资源。
- 删除单个
.resx
文件将“按比例”减少时间;那就是:不幸的是,我没有找到罪魁祸首的单个文件。
Starting a few weeks ago, compiling a project (VB.NET, .NET 2.0, VS 2010) has taken several times as long as before. In Task Manager, I noticed ResXtoResources.exe
taking lots of CPU for a while. I've finally been able to get some data on this using MSBuild's 'Diagnostic' output setting, and comparing that output to what I see in a branch from a few months back. Most striking are the final lines, which give timings. Before:
Target Performance Summary:
[..]
1395 ms CoreResGen 1 calls
1930 ms CompileLicxFiles 1 calls
2135 ms GenerateApplicationManifest 1 calls
2844 ms CoreCompile 1 calls
Task Performance Summary:
[..]
1391 ms GenerateResource 1 calls
1929 ms LC 1 calls
2134 ms GenerateApplicationManifest 1 calls
2843 ms Vbc 1 calls
Build succeeded.
Time Elapsed 00:00:09.50
========== Rebuild All: 5 succeeded, 0 failed, 0 skipped ==========
After:
Target Performance Summary:
1348 ms CompileLicxFiles 1 calls
1747 ms GenerateApplicationManifest 1 calls
2595 ms CoreCompile 1 calls
39575 ms CoreResGen 1 calls
Task Performance Summary:
1347 ms LC 1 calls
1745 ms GenerateApplicationManifest 1 calls
2593 ms Vbc 1 calls
39570 ms GenerateResource 1 calls
Build succeeded.
Time Elapsed 00:00:47.34
========== Rebuild All: 5 succeeded, 0 failed, 0 skipped ==========
Both projects were compiled on the same system with the same settings. We've made numerous changes, to be sure, but nothing to the order of magnitude that would justify such a change in timings (and only for this one task!). I assume resource generation is getting stuck on something — a circular reference, a missing one, etc. I have been unable, however, to find anything useful on how to trace such a problem down to what I assume is just a single resource file.
Short of looking through thousands of checkins or temporarily removing some forms (and thus, their resource files) from the project, is there anything else I can do to figure out the issue? I can't seem to find individual per-resource file timings.
Findings so far:
I've created a new, empty project with all the same .resx
files in place.
- The issue is not reproducible in .NET 4.0: compiling the exact same test project takes less than a second.
- The issue is reproducible in .NET 2.0 as soon as I also add one of the forms from the original project; apparently, it will otherwise not compile the resources "properly".
- Removing individual
.resx
files will reduce the timings 'proportionally'; that is: I have unfortunately not found a single file that is the culprit.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
看起来像 此博客条目给出了答案。
简而言之,在
.resx
文件中搜索实际不存在的程序集引用(例如System.Windows.Forms,版本 4.0.0.0
),然后替换它们与那些这样做(版本2.0.0.0
)。我使用 grepWin 来完成此操作。我的
CoreResGen
/GenerateResource
计时现在与以前大致相同。 CruiseControl.NET 表示构建时间从 92 秒缩短到 40 秒。:)Looks like this blog entry gives the answer.
In a nut, search your
.resx
files for assembly references that don't actually exist (such asSystem.Windows.Forms, Version 4.0.0.0
), and replace them with ones that do (Version 2.0.0.0
). I used grepWin to accomplish this.My
CoreResGen
/GenerateResource
timings are now roughly what they used to be. CruiseControl.NET says build time is down from 92 seconds to 40. :)我在这里找到了原因...资源包含以特殊 Adobe Fireworks 格式 (PNG) 保存的 png 文件。我将文件导出为 png(没有图层信息),现在编译需要 6 秒。
I found the reason here... the resources contained a png file save in special Adobe Fireworks format (PNG). I exported the file to png (without layer information) and now the compile takes 6 seconds.