托管编码员与本地编码员


19

我是一名编码人员,并且具有本机代码和托管代码的经验。我从Pascal和C开始,然后进入C ++,最后进入C#。

在过去的一年左右的时间里,我几乎一直只使用C#进行编码,并且失去了很多当我使用C ++编码器时自然会遇到的东西。

几周前,当我坐下来写一些本机C ++代码时,我发现自己不知所措,因为我逐渐熟悉了这一切的复杂性,怪癖和特质。我几乎不好意思地说,我完全忘记了将动态分配的数组传递给函数而不传递其大小也意味着接收函数将无法知道数组有多长。

有无数的文章和文档将托管代码与非托管代码进行比较和对比。我们都知道,如果优化得很好,本机代码可以比托管代码运行得更快,更轻。另一方面,托管代码具有垃圾收集器以及特定于运行时的CPU和特定于OS的优化,这可以使本机代码运行自如。

纯粹从技术角度来看,没有明确的赢家。

毫无疑问,托管代码在编码和理解上要简单几个数量级。只需看一下在Win32 C ++与C#中构造一个简单GUI所需的行数差异。

早在我的本机编码时代,我主要编写在超级计算机上运行的数学模拟。他们的CLI很难看,而且大多集中在算法上。如今,我用C#编写并生成了精美的GUI应用程序,但是如果我不得不在本地语言上做出类似的口径,那我就会迷路了。即使使用QT之类的框架,在C ++ / QT中生成某些内容所花费的时间仍比在C#中花费两倍。

每当我看到有人用C / C ++编写了一个大型,功能齐全的GUI应用程序时,我都会不禁感到敬畏和嫉妒。

我很好奇其他经验丰富的程序员如何看待托管和非托管语言。您是否将托管代码视为业余爱好者?您是否认为本地编码员更具有核心性

java  .net 

Answers:


26

我目前的日常工作是使用C ++,但是我已经用多种语言进行了足够长的编程,以至于我几乎没有注意到任何区别。这是我的观察结果:

  • C ++程序员经常重新实现许多所谓的其他语言效率低下的最佳实践。我们添加了足够的空检查,数组边界检查,类型检查,输入验证等,从而在很大程度上抵消了该语言不会自动执行这些操作所获得的任何执行速度优势,至少对于不占用大量数据处理的代码而言。
  • 过一会儿,这种多余的样板便成了一种根深蒂固的习惯,因此它并没有真正的额外工作量,并且在丢失时像拇指酸痛地伸出来。
  • 当我使用“托管”语言编程时,我仍然会考虑内存分配,以确保不会造成内存泄漏。我可能没有明确说明delete,但是我仍然意识到垃圾收集器认为它可以删除。我从Java开始解决低内存问题比在C ++中困难得多,这可能是因为在C ++中,很难在很长一段时间内忽略它们。
  • 动态键入也是如此。我仍然必须牢记函数参数是数组,int还是字符串。实际上,这需要更多的精力,因为该类型并未在我这里明确列出。
  • 现代C ++风格与C#之前的时代截然不同。人们没有发现语言的变化,而是“发现”了如何以独特的方式使用现有的C ++功能,从而避免了过去的大部分手动内存管理。自动释放内存的设计模式现在非常普遍。
  • 据我所知,尽管仅通过编写代码就可以制作GUI应用程序,但是QT设计器之类的图形设计器是最受青睐的方法,其中的代码主要仅用于事件处理程序或运行时自定义。
  • 即使您最记得语法,但一段时间以来没有广泛使用的语言总会显得有些笨拙。如果我一年不写python,我会忘记很多特质,即使客观上大多数人都认为python是“更轻松”的语言,但一段时间以来,它比C ++更加尴尬。

综合所有这些因素,在我用C ++和其他语言编程时,我的思维模式保持相当一致,并且差异大多只是语法上的。当然,很多原因是受过训练,习惯,编码标准和现代设计模式的影响,而不是C ++语言本身固有的功能,但是比较仍然存在。

我想我想说的是,根据我的经验,程序员的培训比他所使用的语言要重要得多。


20

您认为托管代码是业余爱好者吗?您是否认为本地编码员更具有核心性?

没有。

我看到了工程师和程序员之间的区别。该铁杆工程师总是会选择语言/技术栈是适当获得在可接受的运行标准的最少时间完成这项工作。

如今,随着处理器能力的提高,通过使用较低级别的本机语言,实际需要从机器中获得尽可能多的东西的频率越来越少。通常,实际上这并不是一个商业案例。生产力总是比执行时间差几毫秒。


+1,但请记住,这是一种经济影响-如果计算周期的成本为100万美元,则将进行极端优化-否则我们根本不会理会计算机……
Gary Rowe

10
除了我们确实看到整体性能较低外-Word6在现代硬件上的运行就像照明一样,Word2010只需一分钟即可加载。今天,我们需要那种超高速硬件来跟上程序员的步伐!
gbjbaanb

2
@gbjbaanb:无论程序员选择什么,任何足够大的代码库都会变慢。IIRC,Word仍然是用C ++编写的(我敢打赌,所有旧版Word 6代码中仍有很大一部分仍然存在)。
史蒂文·埃弗斯

2
@ gbjbaanb,Word 2010不是.NET中Word 6的直接重写。它添加了更多功能,并且必须处理更多使用场景。这是一个多大,比的Word 6大应用
米尔恰Chirea

6

不幸的是,Microsoft导致我们将“托管代码”与C#/。Net类库合并。

这里有两个独立且几乎不相关的事情。

  1. 酷的.Net库。

  2. 托管代码。

C#以整齐,易于使用的易于打包的价格提供两种服务。

C ++有许多很酷的库,几乎可以完成.Net的所有工作。您可以寻找更好的C ++库,而不是将“本机C ++”代码归咎于比C#/。Net代码具有更多的“复杂性,怪癖和特质”。

更好的库也使您可以编写出色的C ++代码。

每当我看到有人用C / C ++编写了一个大型的,功能齐全的GUI应用程序时,我都会感到一种敬畏和嫉妒之情。

错误的政策。相反,您应该找出它们使用了哪些类定义库。您也可以使用这些库。

一切都与工具有关。没有工具,我们只是裤子上的动物。

“本地C ++”并不意味着您应该丢弃所有工具。这意味着您必须找到好的工具。Microsoft不再为您提供帮助,因此您需要花费时间找到合适的工具组合。


为“找出他们正在使用的东西” +1,但坦率地说,我认为这对于使用工具的动物或偶尔碰到裤子的动物不是很好。
伊恩·普格斯利

@伊恩·普格斯利(Ian Pugsley):穿裤子但不使用工具的动物在动物身份上可能还不错。但是您说对了,没有裤子的使用工具的动物可能会生气。例如,我的妻子不喜欢穿裤子,而是使用工具。也许她不会读这个问题。
S.Lott

我们只能希望(并押在相当高的机会上)。我要说的是,我不会看不起一种足够聪明的动物来穿一条裤子……以防万一。
伊恩·普格斯利

是的,与C#的标准库不同,C ++很老,并且缺乏现代需求(GUI,很酷的网络接口等)。
Moshe Revah,2011年

Microsoft再次帮助您在Windows 8中使用C ++(整个Windows 8开发表面是本机代码,C ++与C#和JavaScript一起是一流的公民):msdn.microsoft.com/zh-cn/library/windows/ apps /…
Zach

5

这里的问题与硬核编程无关,而与控制有关。事实是C#以控制成本提供生产力。如果要编写需要大量控制的程序(此内存现在已完全释放),则别无选择,只能使用C ++。如果需要快速完成,则可能需要使用C#。问题在于,C#的支持库比C ++所提供的支持库要好得多和最新。例如,MFC很老很老,它的作法非常糟糕,它大多数是在标准化之前写的。例如,如果Microsoft付出了一些努力来提供新的C ++库,请在Visual Studio 2010中签出新的PPL,那么奇怪的是,在C ++中该任务变得容易了。我认为他们正在以这种方式迁移,

另一方面,托管代码具有垃圾收集器以及特定于运行时的CPU和特定于OS的优化,这可以使本机代码运行自如。

我听说许多托管语言的支持者都这么说,但我几乎从未真正看到它是真的。事实是,除非您要进行非常核心的数学运算,否则更新的CPU中可用的新CPU指令根本无法提供那么多的优势,在这种情况下,您不必承担必须在运行时进行编译或解释的开销-time,您无论如何都可以使用Intel的C ++编译器来使用最新,最强大的SSE。与JIT相比,C ++编译器优化的范围是巨大的,因为JIT必须在程序运行时的一小部分时间内执行,而C ++编译器由于花了很多时间进行编译而颇具传奇色彩。

垃圾回收不是某种神奇的好东西,也不是类似的东西-它是一种算法选择。是否适合所有情况?远不及C#中的IDisposable混乱问题,也不是Java甚至不用费劲尝试解决该问题的方法,而C ++的析构函数将关闭您的文件释放您的内存关闭您的套接字等。GC非常适合某些程序,而不是其他一些。


处理器之间的差异比SIMD还要多-尽管您的C ++编译器可能考虑到的管道与JIT一样多。
彼得·泰勒

在运行时环境中,可以检查系统状态并识别每个可能到达的非固定对象引用,可以用C ++中无法实现的方式摊销许多与GC相关的成本。在Java或C#中,给定String foo,bar;的语句foo=bar;将执行两条指令-寄存器加载和寄存器存储。不变的执行时间,与字符串长度无关。C ++可以接近吗?
2015年

2

在我看来,与C#相比,本机C / C ++看起来像C / C ++本身的汇编程序。像往常一样,另一个复杂的抽象层(并非完全正确,但可以这么说)使您的开发更轻松,但速度有所降低,并且占用了过多的内存。因此,正如我所看到的,它只是分为不同的类别,从而创建了新的程序员子类型。

顺便说一句,由于其C#的抽象水平非常快,Microsoft做得很好。


2

有业余程序员,而不是业余语言。他们拥有的语言(至少是其中的大多数)都有其目的。

我目前正在研究用于测试生产系统的保险计算引擎。生产系统是用C编写的,我们的引擎是用Java编写的,并且由于时间较长,我们的性能要优于C引擎,同时生产率更高。不是因为Java本身比C快,而是因为它足够快并且我们的算法更好,所以我们更轻松地实现了它们,因此可以更快更好地测试和重构代码。

我还编写了测试代码,以将计算结果与生产数据库的内容进行比较:不在C中,不在Java中,而是在Ruby中。同样,它足够快并且需要更少的代码,因此更易于实现,易于测试,易于扩展。

而且,无论我使用哪种语言,我都不会感到业余,只有当我犯了本不应该发生的愚蠢错误时,我才会有这种感觉。


1

去年,我工作的公司通过蛮力对通信CRC代码进行了逆向工程(我们最终得到了它)。3个开发人员都有自己的版本,Borland C,C#.Net 2008,VB6。VB6显然很慢,Borland C很快,但是C#.net却以12倍的速度使它模糊不清。这根本不是我们所期望的。


1
他们是否逐步使用相同的算法?他们可能正在计算相同的输出,但是用于达到输出的基本数学步骤可能会有所不同,而性能由基本步骤的原始计数决定,而原始计数又由“公式”如何分解为它们来确定。
rwong 2011年

较旧的C编译器可能未使用最新的处理器指令(例如SSE2和更高版本)
GrandmasterB,

1
所有这三种语言均可编译为优化的本机代码(在编译期间为VB6 / C ++,在JIT期间为.NET)。因此,您可能正在衡量的是程序员之间的差异,而不是编程语言之间的差异。
尼基,

@nikie JIT!=编译。并且编译器的质量不同。我已经看到用C ++编写的完全相同的算法(没有API调用,只有数组引用,循环和简单的算术)执行速度比Java快得多,尽管大家都在谈论JIT。
quant_dev

1
@quant_dev:根据我的经验什么灵丹妙药;-)我与.NET JIT的经验是,++ JIT和MSVC之间的差别非常小。对于同一代码,我非常怀疑12x的任何一种。
nikie 2011年

1

它取决于多种因素,但基本上,在所有其他条件都相同的情况下,是的,本机代码比托管代码更“硬核”。

但是,对于正常的业务应用程序,我想这通常是一件坏事,因为这意味着普通开发人员必须在代码的非业务方面投入更多的精力。


1

我的程序可以用Java之类的C ++来形容。我的观点是,您可以在Java中实现相同的低级编程,但是它比C ++中的低级编程难得多。但是,通常只需要一小部分代码即可进行这种低级编程,并且在不需要托管语言的情况下,这种编程效率更高。


1

本机开发人员通常以更坚强而闻名,因为他们感到更坚强并采取这种行动。本机开发人员在不容忍任何错误的系统中接受培训,因为它们不可避免地导致硬崩溃或无限制的内存泄漏。特别地,.NET允许进行诸如尝试/捕获所有内容之类的惰性黑客操作,从而使开发人员免于以为他们必须了解核心问题(“ 有时,它只会引发InvalidOperationException。代码很关键! ”)。这并不是一成不变的,但我的观察是在非托管环境中长大的,现在全职使用托管代码。

此外,托管开发人员还倾向于使用更清洁,组织更整齐的BCL。这通常会鼓励他们探索幕后的实际情况。的确,对于STL或Boost,可以说是相同的,但是.NET类库通常足以使我们有时在智力上变得懒惰。

也就是说,编写一个好的,可交付的托管程序需要大量的工作。这意味着以与非托管开发人员类似的方式执行内存和CPU性能分析,单元测试以及代码分析。非托管开发人员倾向于理解这种情况,而托管开发人员倾向于包括更多不这样​​做的人员。

同样,不是黑白的。有许多智力上懒惰的非托管开发人员和核心托管开发人员。从定义上讲,没有一个比另一个更精英。


0

您认为托管代码是业余爱好者吗?您是否认为本地编码员更具有核心性?

这两个世界之间存在鸿沟,我不明白为什么:受管系统是用本机代码编写的(最终,所有内容都在“汇编中”运行)。我想看到的(仍然是我的生活)是一个应用程序构建系统,其中应用程序的所有子任务都将以正确的语言类型编写。


您所描述的应用程序构建系统只是另一种(希望更好)的编程语言。
David Thornley

我不熟悉.NET,但是AFAIK是一个混合语言系统,它具有由VM运行的通用可执行格式可与任何.NET语言一起使用的海量库。在本机/编译环境中,相同的系统会很好。当然,与平台无关。
ern0 2011年

0

Go发布以来,本机代码变得更加容易。我发现它比Java和C#更容易读写。尽管到目前为止,使用Go进行GUI编程并不是很好(我快速浏览了这些选项)。
尽量不要因为与C#相比缺少大型社区种类繁多的库来判断它,因为它仍然被认为是新的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.