(这本来是一个普遍的假设性问题,我抱怨说.NET是一只猪并且乞求理由.这并不是关于我的特定应用程序的问题.)
目前我正在用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数据库中获取数据.然后它使用Linq将其转换为SQL db并发布它.我通过ANTS分析器运行它,似乎数据集填充花费的时间最多.其次是Linq发帖.我知道我的一些领域是反射用法,但我不知道怎么做我需要的东西.我计划将我的字符串更改为字符串构建器.这两者有什么区别吗?
(int)datarow["Index"]
和
ConvertTo.Int32(datarow["Index"])
我更改了所有字符串连接以格式化字符串.这并没有减少头脑.有没有人知道数据读取器与数据适配器和数据集之间的区别?
你对C#和.NET有多熟悉?如果您只是移植保留C++惯用语的遗留代码,我并不感到惊讶它是一种生猪.将应用程序从一个平台逐字移植到另一个平台几乎不是一个好主意.(当然,你没有说过你肯定已经做到了.)另外,如果你是专业的C++开发人员而且是初学的.NET开发人员,你应该期望你的代码就像你在平台上的新手那样表现.
我们无法在不了解更多关于应用程序的情况下确定性能是什么 - 尽管听到字符串连接是罪魁祸首我不会感到惊讶.盒子上有多少个处理器?如果它是2,那么应用程序基本上可以为单个线程占用一切......
在内存方面,.NET通常比C++应用程序更重,但在大多数任务的速度方面至少应该是可比的.拿50MB而不是9MB听起来比我想象的要多,但我不会立刻太担心.
应使用良好的分析器来调查内存和CPU性能.我可以推荐JetBrains dotTrace Profiler,但还有很多其他的.
AFAIK (int)datarow["Index"]
和之间有点差异ConvertTo.Int32(datarow["Index"])
.但是,如果您使用流模式数据读取器,则会有很大差异:
int orderIndex =; using (OdbcDataReader rdr = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) { int Index = rdr.GetInt32(orderIndex); }
该SeqentialAccess
命令的行为是处理SQL结果fastes方式,因为它消除了需要随机访问额外的缓存.
第二个通知是,您似乎正在使用数据集.数据集易于使用,但它们与任何人都称之为"快速"的距离非常远.使用数据集,您基本上运行内存存储引擎(我认为是基于Rushmore).如果你想从RAM的每一位挤出每个CPU周期和所有1,那么你将不得不使用更精简的组件(例如结构的原始数组而不是数据集和数据表).
当你比较苹果和苹果时,CLR可以坚持本地代码.使用NGEN可以在部署时将IL代码本机化.可以避免像边界检查那样的典型CLR开销.只有当您不小心分配时才会发生GC暂停"暂停"(仅因为您有GC并不意味着您应该左右分配).在内存布局方面,CLR实际上有一些优势,因为它可以重新安排内存中的对象以适应访问模式并改善TLB和L2局部性.
顺便说一句,如果你认为关于'C++可以围绕C#运行'的辩论是新事物,我记得C可以围绕C++运行圈子(他们说的'虚拟呼叫很慢')我听说有时间组装在C周围跑圈.