为什么.NET使用这么多CPU,这是一个问题吗?

时间:2009-09-15 19:26:39

标签: .net performance memory-management cpu-usage

(这本来是一个普遍的假设性问题,我抱怨说.NET是猪并且有理由乞求。这并不是关于我的特定应用程序的问题。) < / p>

目前我正在用C#重写一些旧的C ++代码。我们正在移植所有遗留应用程序。我有C ++应用程序,占用MAX 3%CPU。他们大多没有使用。然后我接受代码,复制和粘贴,然后重新格式化为C#语法和.NET库,以及BAM! 50%的CPU。这是什么原因?我起初认为它是JIT,但即使在每个代码路径都进行了练习之后,整个事情也被JIT编辑,同样的问题。

我也注意到了大量的内存增加。花费9 MB运行满载的应用程序现在从10 MB开始,运行速度为50 MB。我意识到硬件很便宜,但我想了解导致这种情况的原因。它是引起恐慌的原因,还是.NET就像猪一样?

更新1回答Skeet

我熟悉C#。我将事情改为Linq,依此类推。我通常采用代码并减少行数,依此类推。你能举一些C ++人在.NET中做错的例子吗?

更新2

这是一般性问题,但具有此问题的具体应用如下。

它有一个线程使用和ODBC驱动程序从paradox db获取数据。然后它使用Linq将其转换为SQL db并发布它。我通过ANTS分析器运行它,似乎数据集填充花费的时间最多。其次是Linq发帖。我知道我的一些领域是反射用法,但我不知道怎么做我需要的东西。我计划将我的字符串更改为字符串构建器。这两者有什么区别吗?

(int)datarow["Index"]

ConvertTo.Int32(datarow["Index"])

我更改了所有字符串连接以格式化字符串。这并没有减少头脑。有没有人知道数据读取器与数据适配器和数据集之间的区别?

5 个答案:

答案 0 :(得分:17)

您对C#和.NET有多熟悉?如果您只是移植保留C ++惯用语的遗留代码,我并不感到惊讶它是一种生猪。将应用程序从一个平台逐字移植到另一个平台几乎不是一个好主意。 (当然,你没有说过你肯定已经做到了。)另外,如果你是专业的C ++开发人员而且是新手.NET开发人员,你应该期望你的代码执行就好像你在平台上是新手。

我们无法在不了解应用程序的情况下确切知道性能如何 - 尽管我听到字符串连接是罪魁祸首并不会感到惊讶。盒子上有多少个处理器?如果它是2,那么应用程序基本上就可以为单个线程占用一切......

.NET在内存方面通常比C ++应用程序更重,但在大多数任务的速度方面至少应该可比。取50MB而不是9MB听起来比我想象的要多,但我不会立即感到担忧。

应使用优秀的分析器调查内存和CPU性能。我可以推荐JetBrains dotTrace Profiler,但还有很多其他的。

答案 1 :(得分:6)

AFAIK (int)datarow["Index"]ConvertTo.Int32(datarow["Index"])之间存在差异。但是,如果您使用流模式数据读取器,则会有很大差异:

int orderIndex = <order of Index column in projection list>;
using (OdbcDataReader rdr = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
{
  int Index = rdr.GetInt32(orderIndex);
}

SeqentialAccess命令行为是处理SQL结果的最佳方法,因为它确实消除了随机访问所需的额外缓存。

第二个通知是,您似乎正在使用数据集。数据集易于使用,但它们与任何人都称之为“快速”的距离非常远。对于数据集,您基本上运行内存存储引擎(我认为它基于Rushmore)。如果你想从RAM的每一位挤出每个CPU周期和所有1,那么你将不得不使用更精简的组件(例如结构的原始数组而不是数据集和数据表)。

当你比较苹果和苹果时,CLR可以坚持本地代码。 IL {1}可以在部署时使用NGEN进行本机化。典型的CLR开销,如bounds checks can be avoided。只有当您不小心分配时才会发生GC暂停“暂停”(仅因为您有GC并不意味着您应该左右分配)。在内存布局方面,CLR实际上有一些优势,因为它可以重新安排内存中的对象以适应访问模式并改善TLB和L2局部性。

顺便说一句,如果你认为“C ++可以围绕C#运行圈子”的争论是新的,我记得C可以围绕C ++运行圈子(他们说的“虚拟呼叫速度很慢”)我听说有时间集合在C周围运行。

答案 2 :(得分:1)

您应该看到CPU使用量有所增加。 3%到50%听起来太多了,这是什么类型的代码?

内存占用只是不可避免的成本。 .NET应用程序在30-50 MB之间的任何事情都是正常的。通常,.NET应用程序的实际内存使用量非常小,但是有一个相当大的运行时开销,这是你无法避免的(这是一次性成本,但它就在那里)如果引用吨组件则非常明显

答案 3 :(得分:0)

我会说内存使用率可能符合预期,但CPU使用率不是。

听起来你有一个没有屈服的线程。

答案 4 :(得分:0)

我可以想到几个猜想:

1)内存 - C ++没有托管内存。因此,它可以逐步释放内存,并在(如果编程良好)最佳时间释放内存。

对于托管内存,程序基本上会“泄漏”内存,直到选择进行垃圾内容处理为止。时间可能取决于为进程分配了多少内存。可能有一种方法可以更改默认行为,但较小的内存大小意味着垃圾收集集合更快,更频繁地发生,这会影响处理时间。如果分配了足够的memo9ry,则可能不需要调用gc。

2)程序是在同一时间运行还是更少?如果它使用5倍的处理器功率但是在1/5的时间内完成,那么所使用的CPU基本上是等效的。

3)是的,.NET可能是一只猪